ThreadLocal内存泄露问题

1.什么情况下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);
}
static class Entry extends WeakReference<ThreadLocal<?>> {
        /** The value associated with this ThreadLocal. */
         Object value;

         Entry(ThreadLocal<?> k, Object v) {
             super(k);
             value = v;
         }
}

从源码中可以看出,对象的引用为 Thread -> ThreadLocalMap ->ThreadLocalMap内部Entry ->ThreadLocal。只要线程一直存在ThreadLocalMap内部Entry一直存在,由于key对应的ThreadLocal为弱引用,只要不存在强引用,就会GC,value为强引用,如果不在最后调用ThreadLocal.remove(),会一直没办法GC,导致内存泄露。

2.如何防止内存泄漏

根据1中分析,每次使用ThreadLocal.set(),最后调用ThreadLocal.remove()就可以了。

3.为什么Entry中的key即ThreadLocal为弱引用,而value为强引用

ThreadLocal设置为弱引用,是为了防止使用ThreadLocal时重新创建

ThreadLocal<String> threadLocal = new ThreadLocal<>();
threadLocal.set("test1");

设置成弱引用,当前面的代码执行完成时,threadLocal对象失去强引用,只剩下Entry中的弱引用,自然可以被GC。不用担心threadlocal.get()会出现什么问题,因为只要可以调用get()就说明强引用还存在(可达的)
当然,如果一开始就使用的ThreadLocal为静态变量,也不会有这种问题。

value设置为强引用,没办法设置为弱引用,因为我们设置值时一般是这样的

threadLocal.set("test1");

这时候的test1除了Entry中的value引用外,不存在其他强引用,设置为弱引用时会被GC回收,这时候恰好调用threadLocal.get(),这是后就会出现bug。

所以,key和value有这种强弱引用之分,和除了Entry以外有没有强引用有关系。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值