tomcat ThreadLocal Leak Prevention Listener究竟做了什么?

时间:2013-02-14 19:45:38

标签: java thread-local thread-local-storage

org.apache.catalina.core.ThreadLocalLeakPreventionListener的文档说“LifecycleListener在停止Context时触发Executor池中线程的更新,以避免线程本地相关的内存泄漏。”

它如何完全阻止ThreadLocal内存泄漏?它是否在上下文停止时显式调用ThreadLocal的remove()方法?

据我所知,ThreadLocal是作为哈希映射实现的。映射键是对ThreadLocal实例本身的引用。映射值是线程本地值。

1 个答案:

答案 0 :(得分:10)

首先澄清一下。当您在应用程序中的ThreadLocal中放置一些自定义类并且取消部署/重新部署该应用程序而不先清除ThreadLocal时,会发生ThreadLocal泄漏。发生这种情况时,线程仍然保存对您的类的引用,该类包含对ClassLoader的引用,ThreadLocal依次保存对您(已取消部署的)Web应用程序加载的所有其他类的引用。

该线程仍然保存对象的引用,因为ThreadLocal值实际存储在内部线程中。无法清除Thread意味着只要ThreadLocal对象正在运行,该特定值就会被保留。

现在回到你的问题 - 如果你忘记删除一些ThreadLocal,它将永远被池线程引用。这就是Tomcat试图阻止的 - 如果怀疑泄漏,则关闭并创建新线程。它对于Web应用程序是不可见的,但是当您停止池线程并将其替换为新线程时,旧的线程将成为引用您的类,类加载器和所有其他内容的最后一个对象。最后,您的{{1}}值符合GC的条件。