引用结构
每个线程都有一个ThreadLocal.ThreadLocalMap
类型的threadLocals
属性, ThreadLocalMap
中使用Entry
来存储线程相关变量,Entry
的key
是对ThreadLocal
的一个弱引用,value
则是Object
类型的线程变量。如下图:
内存泄漏
从引用结构上可以看到,若ThreadLocal
没有被GC Roots
强引用时,在垃圾回收后,ThreadLocal
则会被回收, Entry的key无引用。若线程一直不退出,则value
就一直不会被回收,造成内存泄漏。如下图:
正确使用
内存泄漏的根本原因在于ThreadLocalMap
与Thread
的生命周期一样长,而不是因为弱引用导致内存泄漏的,需要在使用完调用remove
方法手动清除数据,且ThreadLocal
变量应该定义为static
, 保证可以一直访问到,从而可以进行清除操作。