ThreadLocal为什么会出现内存泄露,为什使用弱引用?

ThreadLocal的结构

每个线程有维护了一个ThreadLocalMap,这个ThreadLocalMap的key是ThreadLocal引用,value是ThreadLocal变量真正的值,这个ThreadLocalMap的Entry的key是弱引用,value是强引用。
在这里插入图片描述

为什么使用弱引用?

执行以下测试代码的时候:
在这里插入图片描述
当main线程新建线程调用testThreadLocal时,引用关系是这样的:
在这里插入图片描述
当testThreadLocal执行完成后,testThreadLocal方法栈出栈,引用2和引用3就不存在了,当main方法执行完成后,main方法栈帧出栈,线程销毁,thread引用也不存在了,这时候堆中的所有对象都会被回收,不会出现内存泄露。

但是,如果线程是线程池中的线程,引用1将一直存在,当testThreadLocal执行完后,引用2和引用3不存在了,如果发生了GC,堆中的threadLocalValue这个对象只被一个弱(引用5)所引用,将会被回收,回收后Entry的key为null,但是value依然还存在。
在这里插入图片描述
但是在每次调用set和get方法都会去检查key为null的Entry将value也设置成null,这样的话就多了一层保障。即使没有主动调用remove方法,只要调用了set和get就会将没用的对象引用清除。如果Entry的key不使用弱引用的话,就没办法实现这个功能。

总结

要避免出现内存泄露,主动调用remove方法才是正确的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值