Duplicate :
|
Any java.lang.(Inheritable)ThreadLocals set during the lifetime of a thread, along with the values associated with those ThreadLocals, cannot be garbage collected until the thread itself is garbage collected, even if application code no longer holds references to the ThreadLocals or their values. This occurs because java.lang.Thread uses java.util.IdentityHashMap (as opposed to a "weak" variant of IdentityHashMap) to map ThreadLocals to their associated values; even if the application no longer references a given ThreadLocal, the threadLocals/inheritableThreadLocals map of any thread in which the ThreadLocal was set will retain strong references to both the ThreadLocal and its value, preventing the ThreadLocal and its value from being GC'ed until the referencing thread(s) is also GC'ed. The attached code demonstrates this memory leak. One would expect, instead, that if application code no longer references a ThreadLocal, then that ThreadLocal should be eligible for GC independent of the lifetime of threads in which it was set. This way, if an application creates and discards multiple ThreadLocals (or, perhaps more commonly, multiple objects which each contain ThreadLocals), values associated with the ThreadLocals will still be reclaimable.