【问题标题】:What does tomcat's ThreadLocalLeakPreventionListener do exactly?tomcat 的 ThreadLocalLeakPreventionListener 究竟是做什么的?
【发布时间】:2013-01-30 17:24:17
【问题描述】:

org.apache.catalina.core.ThreadLocalLeakPreventionListener 的文档说

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

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

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

【问题讨论】:

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


【解决方案1】:

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

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

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

【讨论】:

  • 感谢 Tomasz 的出色回应。我只是想知道tomcat“怀疑泄漏”到底是怎么回事?它是否监视线程的空闲时间?或者监控线程是否响应、抛出异常等?
  • @Sumit:不幸的是我不知道。但我怀疑在取消部署期间它必须检查其所有线程池和ThreadLocals。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-13
相关资源
最近更新 更多