ThreadLocal 垃圾回收

2022-01-16 00:00:00 garbage-collection java classloader

来自 javadoc

只要线程处于活动状态且 ThreadLocal 实例可访问,每个线程都持有对其线程局部变量副本的隐式引用;在线程消失后,它的所有线程本地实例副本都将受到垃圾回收(除非存在对这些副本的其他引用).

Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal instance is accessible; after a thread goes away, all of its copies of thread-local instances are subject to garbage collection (unless other references to these copies exist).

由此看来,由 ThreadLocal 变量引用的对象似乎只有在线程死亡时才会被垃圾收集.但是,如果 ThreadLocal 变量 a 不再被引用并成为垃圾回收的对象怎么办?如果持有 a 的线程仍然存在,那么仅由变量 a 引用的对象是否会被垃圾回收?

from that it seems that objects referenced by a ThreadLocal variable are garbage collected only when thread dies. But what if ThreadLocal variable a is no more referenced and is subject for garbage collection? Will object references only by variable a be subject to garbage collection if thread that holds a is still alive?

例如,有以下带有 ThreadLocal 变量的类:

for example there is following class with ThreadLocal variable:

public class Test {
    private static final ThreadLocal a = ...; // references object b
}

这个类引用了一些对象,而这个对象没有其他对它的引用.然后在上下文取消部署应用程序类加载器成为垃圾收集的主题,但线程来自线程池,因此它不会死.对象 b 会被垃圾回收吗?

This class references some object and this object has no other references to it. Then during context undeploy application classloader becomes a subject for garbage collection, but thread is from a thread pool so it does not die. Will object b be subject for garbage collection?

推荐答案

ThreadLocal变量保存在Thread中

ThreadLocal variables are hold in Thread

ThreadLocal.ThreadLocalMap threadLocals;

在当前线程中的第一次 ThreadLocal.set/get 调用时延迟初始化,并保持对 map 的引用,直到 Thread 处于活动状态.然而,ThreadLocalMap 使用 WeakReferences 作为键,因此当 ThreadLocal 从别处被引用时,它的条目可能会被删除.详见 ThreadLocal.ThreadLocalMap javadoc

which is initialized lazily on first ThreadLocal.set/get invocation in the current thread and holds reference to the map until Thread is alive. However ThreadLocalMap uses WeakReferences for keys so its entries may be removed when ThreadLocal is referenced from nowhere else. See ThreadLocal.ThreadLocalMap javadoc for details

相关文章