对于ThreadLocal的一些个人理解

ThreadLocal为什么会导致内存泄漏?

首先给出结论:在ThreadLocal引起的内存泄漏问题中,真正导致内存泄漏的是value,而不是key(ThreadLocal对象本身)

要搞明白一件事情,在Java中一个对象在什么情况下不会被GC掉?根据可达性分析法,如果一个对象存在一个GCRoot对它的引用链, 它就可以保证不被GC回收。

ThreadLocal的本质是每个线程维护一个ThreadLocalMap,并且ThreadLocalMap的每一个Entry都是以这个ThreadLocal对象作为Key(ThreadLocalMap上对这个ThreadLocal对象的引用是弱引用),但是这个Entry上对Value的引用为强引用。

在new一个ThreadLocal对象后(记为tl),这时候这个对象存在一个强引用。在调用这个对象的set或get方法后,又会额外的增加一个ThreadLocalMap对它的弱引用**(WeakReference)。一个对象如果同时存在强引用和弱引用的情况下,是以强引用为主导,即不会被GC回收掉。如果某一时刻tl这个对象为空,也就是JVM堆上的对象失去了强引用,在下一次GC时,这个ThreadLocal对象就会被GC掉。但是由于Value是强引用的,则始终存在着Thread Ref → Thread → ThreadLocalMap→Entry→value的这样一条强引用链(逻辑上不可达,但物理上可达),导致这个value对象既无法被访问,又无法被回收,从而导致内存泄漏。也就是说将ThreadLocal作为弱引用其实是在一定程度上缓解了内存泄漏的问题。

如何避免?

在使用完ThreadLocal时,一定要记得使用Remove()方法,避免造成内存泄漏。

全部评论
后面几句我能不能理解为key不会立刻被gc所以这段时间内value是泄露的,但因为key是弱引用所以很快会被gc,一定程度上缓解了泄露问题
2 回复 分享
发布于 11-07 23:28 美国
这玩意能不能在线程池使用?
1 回复 分享
发布于 11-07 15:26 上海
很详细,感谢
1 回复 分享
发布于 11-07 23:37 江苏
所以你能回答key少线程少,value小为什么也会出现内存泄露?
点赞 回复 分享
发布于 11-07 23:46 北京
那么为什么要这么设计呢,为什么要一个弱一个强引用,而不是都是强或都是弱
点赞 回复 分享
发布于 11-08 14:50 福建
那为什么要把他设置成弱引用呀
点赞 回复 分享
发布于 11-19 09:04 北京

相关推荐

1 tcp挥手是四次,握手为啥是三次不是四次(以为问错了,去回答为啥两次建立不起来连接,再次提醒后才讲了下流程,回答有点乱)2 juc是什么,讲一下3 bean的生命周期4 追问有了解过bean销毁的方法吗5 @GetMapping和@PostMapping的区别    get请求参数能用@RequestBody接收吗 一下子有点懵,回答不能6 mysql的锁(全局,表级锁,行级锁-------然后深入吟唱八股)7 分布式事务的解决方案(回答了Seata和MQ)8 TCC了解吗   完全不会,再也不写了解Cloud了针对实习和项目我的自己的项目是一个12306项目(甲蛙)1 使用布隆过滤器器的参数问题(只记得大概怎么使用,细节记不清了 )2 使用Redis思考过优化什么的吗 (回答请求参数涉及的多可能导致key太长,内存利用率不高,考虑对key压缩...)3 实习里Eureka优化的问题 回答了一二级缓存以及本地列表推送的问题4 实习里多线程优化Excel导出  回答了数据量大超时,oom的产生原因  回答了解决方案反问流程共二面建议多了解一些细节,还有项目别写12306,面试官还以为12306是我写的面试官很好,照着简历上问的,不会的也不会为难人,会给出一些建议。自己有点菜,回答的确实不好,语言组织有点差。最后祝大家都能找到好的工作。
查看13道真题和解析
点赞 评论 收藏
分享
8 38 评论
分享
牛客网
牛客企业服务