ThreadLocal发生内存泄漏的真正原因——豁然开朗

很久很久以前的以前,对于这个问题,网上众说纷纭:key为弱引用,会被下一次gc回收,value强引用,会造成value永远不会回收,然后OOM。

???似懂非懂?懂不了一点?

搞懂就在一瞬间

源码搞起

1、ThreadLocal里面维护了一个ThreadLocalMap。

2、当我们使用ThreadLocal设置值的时候


    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

看重点-------->这个ThreadLocalMap中存放的key是当前线程Thread.currentThread(),当前线程,当前线程,重要的事情说三遍

那也就是说所有使用了ThreadLocal来存放数据的线程共用一个Map,而他们的线程安全是由Map的key不能重复保证的,这时候如果key被回收了,key为null会发生什么?如果再set呢?

回到开头,有没有一瞬间豁然开朗的感觉?

所以,ThreadLocal内存泄漏的真正原因,key被回收,key为null,value一直存在,当线程再来set的时候,就会新加一对新的key和value,如此往复,这个Map总有一天会大到离谱,OOM是必须的了。

ThreadLocal中也提供了remove方法,所以在使用完ThreadLocal的时候记得显示调用下remove方法

     public void remove() {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if (m != null)
             m.remove(this);
     }

  • 46
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: ThreadLocal造成内存泄漏原因是由于ThreadLocalMap的生命周期跟Thread一样长,如果没有手动删除对应的key就会导致内存泄漏,而并不是因为弱引用。\[1\]因此,当ThreadLocal对象被回收后,对应的value仍然存在于ThreadLocalMap中,无法被回收,从而导致内存泄漏。\[1\]但是,只要规范化使用ThreadLocal,并在不需要的时候手动删除对应的key,就可以避免内存泄漏的问题。\[2\]ThreadLocal的实现原理是每个Thread维护一个ThreadLocalMap对象,其中key为弱引用ThreadLocal对象,value为线程变量的副本。\[3\]因此,ThreadLocal并不是洪水猛兽,只要正确使用并遵循规范,就可以避免内存泄漏的问题。\[2\] #### 引用[.reference_title] - *1* *3* [ThreadLocal内存泄漏原因,如何避免](https://blog.csdn.net/weixin_44356698/article/details/118547982)[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^v91^insert_down1,239^v4^insert_chatgpt"}} ] [.reference_item] - *2* [threadlocal内存泄漏原因](https://blog.csdn.net/oliver486/article/details/123798272)[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^v91^insert_down1,239^v4^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值