每个线程都有一个 ThreadLocalMap 的内部属性,map 的 key 是 ThreadLocal,定义为弱引用,value 是强引用类型。
垃圾回收的时候会自动回收 key,而 value 的回收取决于 Thread 对象的生命周期。一般会通过线程池的方式复用线程节省资源,这也就导致了线程对象的生命周期比较长,这样便一直存在一条强引用链的关系:Thread —> ThreadLocalMap —> Entry —> value,随着任务的执行,value 就有可能越来越多且无法释放,最终导致内存泄漏。
解决办法:每次使用 ThreadLocal 就调用它的 remove() 方法,手动将对应的键值对删除,从而避免内存泄漏。