Objective
ThreadLocal
is to provide local variables within a thread that function within the life cycle of the threads, reducing the complexity of the passing of some common variables within the same thread, or between several functions or components. However, if abused ThreadLocal
, it can lead to memory leaks. Below, we will focus on three aspects to analyze ThreadLocal
the problem of memory leaks
ThreadLocal
Implementation principle
ThreadLocal
Why are memory leaks
ThreadLocal
Best practices
ThreadLocal Implementation principle
ThreadLocal
ThreadLocal
Implementation is this: each Thread
maintenance ThreadLocalMap
of a mapping table, the mapping table is the key
ThreadLocal
instance itself, value
is really need to store Object
.
That ThreadLocal
is, itself does not store the value, it is just as one key
to get the thread from ThreadLocalMap
value
. It is worth noting that the dashed line in the diagram indicates that the weak ThreadLocalMap
reference is used ThreadLocal
as Key
the weak reference object is recycled in the GC.
ThreadLocal
Why are memory leaks
ThreadLocalMap
Use a ThreadLocal
weak reference as key
, if ThreadLocal
there is no external strong reference to reference it, then the system GC, this is bound to be ThreadLocal
recycled, ThreadLocalMap
in this case, will appear in key
null
the Entry
, There is no way to access these key
null
Entry
value
, if the current thread no longer end, these key
null
Entry
value
will always have a strong reference chain: Can Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value
never be recycled, Cause a memory leak.
In fact, ThreadLocalMap
the design has taken into account this situation, but also added some protection measures: ThreadLocal
in get()
, set()
, remove()
the time will clear ThreadLocalMap
all the threads key
null
value
.
However, these passive precautions do not guarantee a memory leak:
- When the thread pool is used, it executes the end of the task, the
ThreadLocal
object is recycled, the thread is put back into the thread pool and is not destroyed, and the thread is not being used, causing a memory leak.
- Allocations are used and
ThreadLocal
no longer called, get()
set()
remove()
methods, and memory leaks occur during this period.
Why use weak references
On the surface, the source of the memory leak is the use of weak references. Most of the articles on the Web focus on analyzing why memory leaks, but another issue is equally worth thinking about: Why use weak references? Why not use a strong reference?
Let's take a look at the official documentation:
To help deal with very large and long-lived usages, the hash table entries use weakreferences for keys.
To handle very large and long-time uses, the hash table uses a weak reference key.
We discuss the following in two different situations:
- Key uses strong references : Referenced
ThreadLocal
objects are recycled, but ThreadLocalMap
also hold ThreadLocal
strong references, if not manually deleted, ThreadLocal
will not be recycled, resulting in Entry
memory leaks.
- Key uses weak references : The referenced
ThreadLocal
objects are recycled, and because ThreadLocalMap
of the weak references that are held, they are ThreadLocal
recycled even if they are not manually deleted ThreadLocal
. value
ThreadLocalMap
set
get
It will be cleared at the next call.
Comparing two cases, we can find that because ThreadLocalMap
the life cycle is the Thread
same length, if not manually delete the corresponding key
, will lead to a memory leak, but the use of weak references can be a layer of protection: Weak references are ThreadLocal
not memory leaks, the value
corresponding At the next ThreadLocalMap
call set
, get
remove
the time will be cleared .
Therefore, the source of the ThreadLocal
memory leak is that because ThreadLocalMap
the life cycle is the Thread
same length, it causes a memory leak if not manually deleted key
, not because of a weak reference.
ThreadLocal Best Practices
Combined with the above analysis, we can understand ThreadLocal
the causes and consequences of memory leaks, so how to avoid memory leaks?
- Each time it is used, the
ThreadLocal
method is called remove()
and the data is purged.
In the case of using the thread pool, there is no timely cleanup ThreadLocal
, not only the memory leak problem, but more serious is likely to cause problems in business logic. So, use ThreadLocal
just as the lock to unlock the same, run out to clean up.
Deep analysis of ThreadLocal memory leaks