# ThreadLocal为什么会内存泄漏?

注意:不是因为key是弱引用。

理解关键点:ThreadLocal的生命周期它是和线程绑定的。

问题1:那么ThreadLocal的数据存在哪里呢?

答:数据不存在ThreadLocal对象的本身,而是在每一个ThreadLocal对象里面它会有个ThreadLocalMap的一个私有变量。你可以把这个map想象成一个线程专属的一个小仓库。那么这就导致了一个关键问题。问题2的引出

问题2:如果线程本身它不结束,这个小仓库就会一直存在的一个问题!

答:想象一个场景假如我们在线程池里面去用ThreadLocal,那么这些工作线程会长期的存活着。反复的去执行任务就存问题了。

问题3:当你在线程外将某个ThreadLocal对象实例设置为null。希望它会被回收的时候发现它依然还占这内存。为什么会占这内存呢?

答:因为线程还在嘛。ThreadLocalMap还存在。map里面对应的那个ThreadLocal的引用也就还存在。这就造成了一堆你已经不再使用的无效数据没法被回收。导致了内存的泄漏问题。

问题4:怎么缓解这个内存泄漏问题呢?

答:JDK的设计者引入了二个关键的机制。

**第一个关键的机制:**将map里面的key也就是ThreadLoca对象本身设计为弱引用。那么弱引用的作用就是我在回收的时候不管内存足部足。我都会被回收。解决了:线程还在,一旦我们将ThreadLoca的变量设置为null。那么这个key也会在GC的时候清理掉。map里面就对应的条目就会变为一个:

key = null
1

value有值的一个状态。但是又引出了下一个问题。

问题5:那么key被回收了,value还在的问题!

**第二个关键的机制:**那么这些key为null的entry以及它们对应的value对象依然还占着内存的。所以它依然还会导致一个内存泄漏问题。所以在ThreadLoca内部它内置了一些清理的机制。比如说:set、get、remove方法的时候会顺带的将这些无效的key=null的一些条目给清理掉。但是这也绝对不能百分百的及时清理。

不及时调用这些方法导致的问题:

数据会一直堆积在内存里面。

最有效的解决办法

用完后及时的手动的去remove,remove以后这些对象都会被回收掉。

Last Updated: 4/3/2026, 6:47:37 AM