
每个线程中都有一个映射. 映射的类型是ThreadLocal. ThreadLocalMap. 映射中的键是ThreadLocal实例. 该映射确实使用弱引用,但弱引用仅用于键. 每个键都有一个对ThreadLocal实例的弱引用点. 当threadlocal ref设置为null时,没有对ThreadLocal实例的强引用,因此ThreadLocal实例将由gc恢复. 但是,我们的值无法恢复,因为当前线程存在一个强引用. 只有在当前线程结束之后,当前线程ref才会在堆栈中不存在,强引用将断开连接,并且当前线程Map的值将全部由GC恢复.

因此,可以得出结论,只要gc回收了线程对象,就不会发生内存泄漏,但是当threadLocal设置为null且线程结束时,它将不会被回收,我们认为发生内存泄漏. . 实际上,这是对该概念的不一致理解,没有什么可争论的. 最可怕的是线程对象没有被回收threadlocal内存泄露,这导致了真正的内存泄漏. 例如,当使用线程池时,线程的末尾不会被破坏,而是会再次使用. 可能有内存泄漏.
返回到内存泄漏是由于WeakReference Key问题所致. 当然,Java中的每个人都早就想到了这个问题. 如果key == null,则可以认为该值无效,可以调用expunged清除它.

这个expungeStaleEntry方法将在get和set期间间接调用threadlocal内存泄露,并且该调用也将显示在remove方法中,这就是为什么有些文章说程调用完成之后,可以对remove方法的调用是有效杜绝泄漏的原因.
只有在以下情况下才可能泄漏的点

:
1. 线程的run方法结束后,调用remove进行清理

2. 线程程池模式下反复运行
threadLocal.remove();
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-239844-1.html
可见一斑