很久很久以前的以前,对于这个问题,网上众说纷纭:key为弱引用,会被下一次gc回收,value强引用,会造成value永远不会回收,然后OOM。
???似懂非懂?懂不了一点?
搞懂就在一瞬间
源码搞起
1、ThreadLocal里面维护了一个ThreadLocalMap。
2、当我们使用ThreadLocal设置值的时候
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
看重点-------->这个ThreadLocalMap中存放的key是当前线程Thread.currentThread(),当前线程,当前线程,重要的事情说三遍
那也就是说所有使用了ThreadLocal来存放数据的线程共用一个Map,而他们的线程安全是由Map的key不能重复保证的,这时候如果key被回收了,key为null会发生什么?如果再set呢?
回到开头,有没有一瞬间豁然开朗的感觉?
所以,ThreadLocal内存泄漏的真正原因,key被回收,key为null,value一直存在,当线程再来set的时候,就会新加一对新的key和value,如此往复,这个Map总有一天会大到离谱,OOM是必须的了。
ThreadLocal中也提供了remove方法,所以在使用完ThreadLocal的时候记得显示调用下remove方法
public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}
标签:Thread,remove,value,ThreadLocal,线程,内存,key,豁然开朗
From: https://blog.csdn.net/weixin_45967584/article/details/137204111