gc后key为null,但是值不为null。 需要注意的是,这里立即释放了对threadLocal实例的强引用,帮助gc回收。查看弱引用的使用方法 原因 ThreadLocal#set后会将threadLocal实例本身作为key 放入Thread.currentThread().threadLocalMap中,与set的value构成一对Entry。而Entry使用了threadLocal的实例作为弱引用。因此当发生gc的时...
ThreadLocal对象被GC回收了,那么key变成了null。Map又是通过key拿到的value的对象。所以,GC在回收了key所占内存后,没法访问到value的值,因为需要通过key才能访问到value对象。如图所示的引用链:CurrentThread → Map(ThreadLocalMap) → Entry → value ,所以在当线程没有被回收的情况下,value所占内存也不会被回收。
Thread类有一个类型为ThreadLocal.ThreadLocalMap的实例变量,key为ThreadLocal的弱引用,value为代码中放入的值。 内存泄露 内存泄露为程序在申请内存后,无法释放已申请的内存空间,一次内存泄露的危害可以忽略,但内存泄露堆积后果很严重。 提出一个问题:GC 之后 key 是否为null? 四种引用类型 强引用:我们常常 new 出来...
导致Entry的Key为null,如果这时value外部也没有强引用指向它,那么value就永远也访问不到了,按理也应该被GC回收,但是由于Entry对象还在强引用value,导致value无法被回收,这时「内存泄漏」就发生了,value成了一个永远也无法被访问,但是又无法被回收的对象。
此时我们看到,该对象的确已经为null了。此时,我们更换写法。 诶?问题来了。为什么这个弱引用在发生一次GC后,值依然可以获取到呢?是弱引用的引用链没有消失么?不,真相是我们此时的new Test()对象也恰巧被一个test强引用所指向,因此发生了GC也无法回收掉。这与我们ThreadLocal中,Entry的key断开与new ThreadLocal()...
可见ThreadLocal的使用没有受到gc的影响,原因何在? 我们先分析一下里面的引用链,其中实线为强引用,虚线为弱引用 image.png 可见,现在的ThreadLocal,是有两条引用链的,一条是当前线程中的,由线程指向ThreadLocalMap,通过Map指向Entry,而Entry指向key;另一条引用链则是当前执行的测试类的成员变量:TestThreadLocal#LOC...
仔细观察 ThreadLocalMap,这个 map 是使用 ThreadLocal 的弱引用作为 Key 的,弱引用的对象在 GC 时会被回收。因此使用了 ThreadLocal 后,引用链如图所示 图中的虚线表示弱引用。这样,当把 ThreadLocal 变量置为 null 以后,没有任何强引用指向 ThreadLocal 实例,所以 ThreadLocal 将会被 GC 回收。这样一来...
1.ThreadLocal对象在实际应用中是否应该总为static(不使用static无法成为一个全局的上下文)?但这不就跟ThreadLocalMap中Entry的key是对ThreadLocal的WeakReference冲突了?因为threadLocal对象是static的,会一直在方法区,所以Entry的key就不可能会因为gc而变为null,,此时ThreadLocal的自动回收失效,必须使用后手动remove()2....
ThreadLocalMap有点类似HashMap的结构,只是HashMap是由数组+链表实现的,而ThreadLocalMap中并没有链表结构。我们还要注意Entry, 它的key是ThreadLocal<?> k ,继承自WeakReference, 也就是我们常说的弱引用类型。 GC 之后key是否为null? 回应开头的那个问题, ThreadLocal 的key是弱引用,那么在threadLocal.get()的...