4

文档org.apache.catalina.core.ThreadLocalLeakPreventionListener

A在停止LifecycleListener时触发 Executor 池中的线程更新,Context以避免与线程本地相关的内存泄漏。

它如何准确地防止ThreadLocal内存泄漏?上下文停止时是否显式调用ThreadLocal'方法?remove()

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

4

1 回答 1

12

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

并且线程仍然持有对您的对象的引用,因为ThreadLocal值实际上存储线程内部。未能清除ThreadLocal意味着该特定值将由Thread对象持有,只要它正在运行。

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

于 2013-02-14T19:58:02.627 回答