ThreadLocal原理及内存泄漏分析

本文详细解释了ThreadLocal的工作原理及内存泄漏的原因。由于ThreadLocalMap的生命周期与线程一致,且其内部使用弱引用保存ThreadLocal对象作为键,因此当ThreadLocal对象被垃圾回收时,若未手动调用remove()方法清理,会导致value无法被访问,从而引发内存泄漏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用ThreadLocal时需注意,一定要及时调用remove()方法清楚ThreadLocal,否则会发送内存泄漏,最终导致内存溢出

ThreadLocal的原理:每个Thread类有个ThreadLocalMap,而ThreadLocal本身并不存储数据,使用ThreadLocalMap来存储(相当于Map的功能,只不过它存储用的Entry节点而不是Entry链表),这个ThreadLocalMap的key是ThreadLocal对象本身,value就是要存储的value。

ThreadLocal内存泄漏的原因:基于上面的原理,分析下内存泄漏的原因。因为ThreadLocalMap的生命周期和当前线程Thread是一样的(通过源码可知:t.threadLocals = new ThreadLocalMap(this, firstValue);),而ThreadLocalMap的key是ThreadLocal,他们之间弱引用(见源码:static class Entry extends WeakReference<ThreadLocal> {
/** The value associated with this ThreadLocal. */),所以当ThreadLocal被回收的时候,ThreadLocalMap的key就为null了,对应的value找不到了,导致了内存泄漏。jdk也有些保障措施,在我们调用set()、get()的时候,会清楚key为null的数据,但是这样被动清楚也不能完全避免内存泄漏。

扩展:为什么用弱引用而不用强引用,其实这也是jdk的保障措施,因为如果是强引用,那么ThreadLocal也不能被回收,会造成更大的内存浪费。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值