# ThreadLocal 有哪些内存泄露问题,如何避免

每个 Thread 都有一个 ThreadLocal.ThreadLocalMap 的 map,该 map 的 key 为 ThreadLocal 实例,它为一个弱引用,我们知道弱引用有利于 GC 回收。当 ThreadLocal 的 key == null 时,GC 就会回收这部分空间,但是 value 却不一定能够被回收,因为他还与 Current Thread 存在一个强引用关系,如下

image 由于存在这个强引用关系,会导致 value 无法回收。如果这个线程对象不会销毁那么这个强引用关系则会一直存在,就会出现内存泄漏情况。所以说只要这个线程对象能够及时被 GC 回收,就不会出现内存泄漏。如果碰到线程池,那就更坑了。 那么要怎么避免这个问题呢? 在前面提过,在 ThreadLocalMap 中的 setEntry ()、getEntry (),如果遇到 key == null 的情况,会对 value 设置为 null。当然我们也可以显示调用 ThreadLocal 的 remove () 方法进行处理。 下面再对 ThreadLocal 进行简单的总结:

  • ThreadLocal 不是用于解决共享变量的问题的,也不是为了协调线程同步而存在,而是为了方便每个线程处理自己的状态而引入的一个机制。这点至关重要。
  • 每个 Thread 内部都有一个 ThreadLocal.ThreadLocalMap 类型的成员变量,该成员变量用来存储实际的 ThreadLocal 变量副本。
  • ThreadLocal 并不是为线程保存对象的副本,它仅仅只起到一个索引的作用。它主要是为每一个线程隔离一个类的实例,这个实例的作用范围仅限于线程内部。