对于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()方法,避免造成内存泄漏。

全部评论
这玩意能不能在线程池使用?
1 回复 分享
发布于 今天 15:26 上海

相关推荐

你是来当牛马的吧:好强,在这个世界上竟然有人能写出如此优秀的代码,可恶啊!
点赞 评论 收藏
分享
有趣的牛油果开挂了:最近这个阶段收到些杂七杂八的短信是真的烦
点赞 评论 收藏
分享
过往烟沉:我说什么来着,java就业面就是广!
点赞 评论 收藏
分享
2 收藏 评论
分享
牛客网
牛客企业服务