ThreadLocal导致内存泄漏分析以及解决方案
场景A、假设ThreadLocalMap中的key使用了强引用,那么会出现内存泄漏吗 ?
1、假设在业务代码中使用完ThreadLocal对象,ThreadLocalRef引用 会被回收了
2、但因为ThreadLocalMap的Entry中key强引用了ThreadLocal对象,造成该对象无法被回收
3、在没有手动删除这个Entry以及当前 CurrentThread线程对象依然运行的前提下,
始终有强引用链 CurrentThreadRef引用--->CurrentThread线程对象--->ThreadLocalMap-->Entry(Entry中的key指向ThreadLocal对象);
所以Entry没法被回收,同时导致new ThreadLocal()对象也没法被回收,导致内存泄漏

场景B、假设ThreadLocalMap中的key使用了弱引用
使用完 ThreadLocal对象 ,threadLocalRef引用 会被回收,但因为ThreadLocalMap的Entry中key只是弱引用了ThreadLocal对象。所以threadlocal对象同时也可以被回收,
此时 Entry 中的 key = null。但没有手动删除这个 Entry 或者 CurrentThread 依然运行,依然存在强引用链,value 不会被回收,而这块 value 永远不会被访问到,
也会导致 value 内存泄漏

三、两个主要原因:
1、 没有手动删除这个 Entry
2、CurrentThread 依然运行
根本原因:ThreadLocalMap 是 Thread的一个属性,生命周期跟 Thread 一样长,如果没有手动删除对应 Entry 就会导致内存泄漏
解决方法:使用完 ThreadLocal 中存储的内容后将它 remove 掉就可以
ThreadLocal 内部解决方法:在 ThreadLocalMap 中的 set/getEntry 方法中,通过线性探测法对 key 进行判断,如果 key 为 null(ThreadLocal 为 null)会对 Entry 进行垃圾回收。
所以使用弱引用比强引用多一层保障,就算不调用 remove,也有机会进行 GC

浙公网安备 33010602011771号