存在场景ThreadLocal使用结束后,将ThreadLocal置为null,伪代码如下:
ThreadLocal<String> a = new ThreadLocal<>();
a.set("测试value");
a=null;
1.为什么ThreadLocalMap的Entry中的ThreadLocal是弱引用?
如果Entry中的key为强引用
1.对象a断开了与堆中ThreadLocal对象的强引用;
2.Entry中的key持有ThreadLocal对象的强引用。
如果一个对象具有强引用,那垃圾回收器绝不会回收它
即便将a置为null,a指向的ThreadLocal对象也不会被回收
如果Entry中的key为弱引用
1.对象a断开了与堆中ThreadLocal对象的强引用;
2.Entry中的key持有ThreadLocal对象的弱引用。
当垃圾回收器发现的对象仅有弱引用时,不管当前内存空间足够与否,都会回收它的内存
将a置为null后,a指向的ThreadLocal对象可顺利回收
2.ThreadLocal为什么会发生内存泄露?
由1得出,当a置为null后,因为弱引用的关系,Entry的key(ThreadLocal)可顺利回收
Entry的key被回收后,就会导致value成为一个不可达的强引用对象,此时value就会随Entry的回收而回收。
若线程由线程池调用且一直不被销毁,ThreadLocalMap不回收,因此产生了内存泄露。
因此在ThreadLocal使用结束后,必须要使用.remove()方法,将其value置为null,避免产生内存泄露。