ThreadLocal为什么会出现内存泄漏,你真的知道吗?

原文链接:ThreadLocal为什么会出现内存泄漏,你真的知道吗? – 编程屋

目录

1 前言

2 ThreadLocal进行线程隔离的小示例

3 原因

1 前言

大家想要搞清楚这个问题,就必须知道内存泄漏和内存溢出的区别

内存泄漏:不就被使用的对象或者变量无法被回收

内存溢出:没有剩余的空间来创建新的对象

2 ThreadLocal进行线程隔离的小示例

同一个threadlocal对象,不同线程之间存储的值是获取不到的

public class QuThreadLocal {

  static ThreadLocal<Wolf> t1 =  new ThreadLocal<>();

    public static void main(String[] args) {
        new Thread(()->{
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            t1.set(new Wolf("小王"));
            System.out.println(t1.get());
            t1.remove();
        }).start();


        new Thread(()->{
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(t1.get());
        }).start();
    }
}

控制台输出: 

 可以发现在不同的线程里面放置东西,其它线程里面是找不到的。

解析原因,观察是如何向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);
    }
    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

1)先获取当前线程t,然后根据t获取threadmap对象

2)判断map是否为null,map不为null时,将当前threadllocal对象作为key,想要设置的值作为value放置其中,否则就创建一个map。创建map的key值与上相同。

这也表明了,存储的值只有当前线程才能够获取到。

3 原因

threadlocal内部结构:

造成内存泄漏的原因:

        由于Entry中的value是强引用,key是弱引用;当垃圾回收器回收threadlocal时,由于value是强引用,不能被回收,所以造成了内存泄漏。

        因此,ThreadLocal内存泄漏的根源是:由于ThreadLocalMap的生命周期跟Thread一样长,如果没有手动删除对应的key就会导致内存泄漏,而并不是因为弱引用。

解决方案一:扩大成员变量Threadlocal的一个作用域,避免被GC回收(不推荐)

解决方案二:每次使用完threadlocal之后,就调用remove方法去移除对应的数据(推荐)

以上只是部分内容,为了维护方便,本文已迁移到新地址:ThreadLocal为什么会出现内存泄漏,你真的知道吗? – 编程屋

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值