一般开发时,会声明静态的ThreadLocal,
如:
static ThreadLocal threadLocal = new ThreadLocal();
假设key强引用,那Entry对象就被ThreadLocal强引用了(看第一段代码-假设没有弱引用的Entry),但是ThreadLocal是静态变量,即静态变量本身就是GC root,因此threadLocal自然不会被垃圾回收
Entry中的key又强引用于threadLocal,则整个entry永远都不会被GC,必然就会内存泄漏了
假设没有弱引用的Entry
static class Entry {
/** The value associated with this ThreadLocal. */
Object value;
ThreadLcoal key;
Entry(ThreadLocal<?> k, Object v) {
/** 从这里可以看出,入参就是 声明静态的ThreadLocal 对象**/
key = k;
value = v;
}
}
现在弱引用就相当于把threadLocal 和 entry切断了,可以理解为GC的时候,对entry做可达性分析时,就关联不到threadLocal,entry唯一引用他的就是线程本身了,但是线程一结束就销毁了,线程对象本身也得被GC,那此时entry就也得回收了
Entry官方源码
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
当然,如果threadLocal是局部变量(方法内变量),就算是强引用,也不会有内存泄漏问题,因为线程一结束,threadLocal和thread都没有任何引用了,GC就会都回收掉,但是谁会把ThreadLocal设置成局部变量呢?