【问题标题】:why webappclassloader is not garbage collected ?为什么 webappclassloader 不被垃圾收集?
【发布时间】:2014-08-08 13:04:32
【问题描述】:

我有一个由spring/hibernate开发的web服务,当我在Tomcat 7上多次部署和取消部署时,我得到一个outOfMemoryError PermGen内存泄漏。

通过使用 java VisualVM,我注意到之前的 webappClassLoader 仍然保存在 JVM 中,因此它们没有被垃圾回收。

这个问题的原因是什么?

如何检测哪些对象仍然引用应用程序类加载器或由它加载的任何对象?

谢谢,

【问题讨论】:

标签: java hibernate tomcat memory-leaks garbage-collection


【解决方案1】:

简短的回答是您有内存泄漏。根据经验,这很可能出现在您的 Web 应用程序或它正在使用的库中。您也有可能(但不太可能)在 Tomcat 中发现了内存泄漏。

追踪内存泄漏的简短版本是:

  • 启动 Tomcat
  • 取消部署并重新部署有问题的应用程序一次
  • 使用分析器检查堆
  • 查找 WebappClassLoader 的实例
  • 找到被强持有但属性为started = false的那个
  • 跟踪该 WebappClassLoader 实例的 GC 根
  • 这将指向您的内存泄漏

找到内存泄漏的根本原因可能有点困难。

有关如何追踪此类内存泄漏以及可能导致它们的原因的更完整说明,请参阅此演示文稿:http://people.apache.org/~markt/presentations/2010-08-05-Memory-Leaks-JavaOne-60mins.pdf

【讨论】:

  • 这会因为演示链接而获得 +1。然后我注意到你实际上是它的作者。我读过的关于这个主题的最好的材料,我现在想知道为什么这是我第一次读它。谢谢你:)
  • 谢谢!正如你所说,我得到了已启动的 WebappClassLoader 实例 = false。问题是要跟踪 GC 根!我怀疑没有停止的 TimerThread !那么在网络应用程序取消部署后我该怎么做才能停止这个线程?
  • 使用 ServletContextListener 并在 contextDestroyed() 事件中停止线程。
猜你喜欢
  • 1970-01-01
  • 2010-12-19
  • 1970-01-01
  • 2013-04-25
  • 2017-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多