ThreadLocal的弱引用

ThreadLocal中,获取到线程私有对象是通过线程持有的一个threadLocalMap,然后传入ThreadLocal当做key获取到对象的,这时候就有个问题,如果你在使用完ThreadLocal之后,将其置为null,这时候这个对象并不能被回收,因为他还有 ThreadLocalMap->entry->key的引用,直到该线程被销毁,但是这个线程很可能会被放到线程池中不会被销毁,这就产生了内存泄露,jdk是通过弱引用来解决的这个问题的,entry中对key的引用是弱引用,当你取消了ThreadLocal的强引用之后,他就只剩下一个弱引用了,所以也会被回收。

看代码 threadLocal是一个强引用,引用了堆中ThreadLocal对象A,然后调用set方法时,在当前线程的threadLocalMap中也引用了对象A,即entry中的key,如果entry中的key不设为弱引用的话,就会存在上面说的对象A内存泄露的问题。

ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();
threadLocal.set(1);
threadLocal.get();
threadLocal = null;



作者:吕清海
链接:https://www.zhihu.com/question/37401125/answer/337717256
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

ThreadLocal在解决完Entry中的key内存泄露问题后,还有一个内存泄露问题,就是Entry中的value

因为只有key是弱引用,当上面threadLocal强引用变空时,entry.key也会被回收,这个时候还剩下Entry和Entry中的value。

因为entry是跟threadLocalMap绑定在一起的,threadLocalMap又是跟Thread绑定在一起的。所以只要线程没销毁的话,这个entry就不会被销毁,这样就内存泄露了。

ThreadLocal提供了这个问题的解决方案。

每次操作set、get、remove操作时,ThreadLocal都会将key为null的Entry删除,从而避免内存泄漏。

那么问题又来了,如果一个线程运行周期较长,而且将一个大对象放入LocalThreadMap后便不再调用set、get、remove方法,此时该仍然可能会导致内存泄漏。

这个问题确实存在,没办法通过ThreadLocal解决,而是需要程序员在完成ThreadLocal的使用后要养成手动调用remove的习惯,从而避免内存泄漏。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ThreadLocal中使用弱引用的原因是为了解决内存泄漏的问题。当我们将ThreadLocal对象置为null后,如果ThreadLocalMap中的entry的key仍然是强引用,那么对象A就无法被回收。因为ThreadLocalMap中的entry会持有key的引用,直到该线程被销毁。然而,线程很可能会被放到线程池中重复使用,导致内存泄漏。 通过使用弱引用,当ThreadLocal对象的强引用被取消后,它就只剩下一个弱引用了。弱引用在JVM触发GC回收时会被回收。因此,在下一次调用get()、set()、remove()方法时,ThreadLocalMap中的key为null的entry就会被删除,实现了惰性删除和释放内存的作用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [ThreadLocal弱引用](https://blog.csdn.net/AAA821/article/details/103794227)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [Threadlocal中的弱引用到底是怎么一回事](https://blog.csdn.net/m0_59602613/article/details/123759760)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值