面试题- ThreadLocal内存泄漏问题

前言

探究 ThreadLocal 内存泄漏问题

弱引用: 每次 GC 都会回收

测试代码

package test;

import java.lang.ref.WeakReference;

public class WeakReferenceTest {

    public static void main(String[] args) {
        // 弱引用 this.referent指向引用对象
        WeakReference<byte[]> weakReference = new WeakReference<>(new byte[10]);
        System.out.println(weakReference.get());
        // gc,回收弱引用
        System.gc();
        // null
        System.out.println(weakReference.get());

        /**
         * ThreadLocal中的弱引用
         * ThreadLocal中的ThreadLocalMap的Entry节点继承自WeakReference
         */
        ThreadLocal<Integer> t1 = new ThreadLocal<Integer>();
        System.out.println(t1);
        Integer i1 = 134;
        t1.set(i1);
        // 置空,gc回收new ThreadLocal对象(该对象也被WeakReference引用)
        t1 = null;
        // t1.remove();
        // 查看Thread类的threadLocals的Entry节点
        Thread thread = Thread.currentThread();
        System.out.println("thread = " + thread);

        System.gc();

        // 再次查看Thread类的threadLocals的Entry节点,弱引用被gc
        System.out.println("gc()...");
    }
}

debug 测试代码

查看 thread 对象中 referent 的变化

在这里插入图片描述
执行 System.gc() 后, referent 对象被置为 null ,但是 value 值仍在。
在这里插入图片描述

value 值还存在

下面截取 TreadLocal 中源码

     /**
         * The entries in this hash map extend WeakReference, using
         * its main ref field as the key (which is always a
         * ThreadLocal object).  Note that null keys (i.e. entry.get()
         * == null) mean that the key is no longer referenced, so the
         * entry can be expunged from table.  Such entries are referred to
         * as "stale entries" in the code that follows.
         */
        static class Entry extends WeakReference<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

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

说明:Entry 继承了 WeakReference,但是调用了super传递的是 t1 这个对象。
t1两处引用,一个t1 = new,一个被弱引用了。
t1=null,然后t1就只有被弱引用,调用gc , t1 也被回收了
然后value这个就再也访问不到了,也清除不了。

参考

ThreadLocal内存泄漏问题
弱引用WeakReference作用与使用场景
一个场景Demo分析ThreadLocal使用方法和原理

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值