问题回答
我们知道,ThreadLocal 是基于 ThreadLocalMap 实现的,这个 Map 的 Entry 继承了 WeakReference ,而 Entry 对象中的 key 使用了 WeakReference 封装,也就是说 Entry 中的 key 是一个弱引用类型,而弱引用类型只能存活在下次GC之前。
如果线程调用 ThreadLocal 的 set 设置变量,当前 ThreadLocalMap 则会新增一条记录,但由于发生了一次垃圾回收,此时的key 值就会被回收,而 value 值依然存在在内存中,由于当前线程一直存在,所以 value 值将一直被引用。
这些被垃圾回收掉的 key 就会一直存在一条引用链的关系:Thread --> ThreadLocalMap --> Entry --> Value。这条引用链会导致 Entry 不会被回收,Value 也不会被回收,但 Entry 中的 key 却已经被回收的情况发生,从而造成内存泄漏。
我们只需要在使用完该 key 值之后,将 value 值通过 remove 方法 remove 掉,就可以防止内存存泄露了。