ThreadLocal memory leaks
Entry method according to the source above, we know ThreadLocalMap using ThreadLocal weak references as the Key . The figure is showing the relationship between a reference herein to introduce some of the objects, a solid line indicates strong reference, dotted line indicates weak references:
As shown above, ThreadLocalMap use weak references ThreadLocal as a key, if not a ThreadLocal external references cited his strong, then the system gc time, this ThreadLocal bound to be recovered, so that, ThreadLocalMap key is null will appear in the Entry, there is no way to access the key for the Entry of the value null if the current thread still delay the end, these key for the Entry of the value null will always exist a strong reference to the chain:
the thread Ref -> the thread -> ThreaLocalMap -> Entry -> value
can never be recovered, resulting in a memory leak.
ThreadLocal的hashcode
In ThreadLocalMap
the need to get the index i, set
int i = key.threadLocalHashCode & (len-1);
The key herethreadLocalHashCode
Here modeled ThreadLocal to runthreadLocalHashCode
Single-threaded, multi-instantiated
public class ThreadLocalMapDemo {
private final int threadLocalHashCode = nextHashCode();
private static AtomicInteger nextHashCode =
new AtomicInteger();
private static final int HASH_INCREMENT = 0x61c88647;
private static int nextHashCode() {
return nextHashCode.getAndAdd(HASH_INCREMENT);
}
public static void main(String[] args) {
System.out.println(new ThreadLocalMapDemo().threadLocalHashCode);
System.out.println(new ThreadLocalMapDemo().threadLocalHashCode);
System.out.println(new ThreadLocalMapDemo().threadLocalHashCode);
System.out.println(new ThreadLocalMapDemo().threadLocalHashCode);
}
}
Output:
0
1640531527
-1013904242
626627285
Multi-threaded, single instantiation
public class ThreadLocalMapDemo {
private final int threadLocalHashCode = nextHashCode();
private static AtomicInteger nextHashCode =
new AtomicInteger();
private static final int HASH_INCREMENT = 0x61c88647;
private static int nextHashCode() {
return nextHashCode.getAndAdd(HASH_INCREMENT);
}
public static void main(String[] args) {
for(int i=0;i<5;i++){
new Thread(() -> {
System.out.println("threadName:"+Thread.currentThread().getName()+":"+new ThreadLocalMapDemo().threadLocalHashCode);
}).start();
}
}
}
Output:
threadName:Thread-0:0
threadName:Thread-1:1640531527
threadName:Thread-2:-1013904242
threadName:Thread-3:626627285
threadName:Thread-4:-2027808484
Magic number 0x61c88647
reference:
Advanced Java (seven) correctly understand and apply the principles of Thread Local Scene
ThreadLocal source detailed analysis, the magic number 0x61c88647