如何使用免费工具查找类加载器泄漏?

Posted

技术标签:

【中文标题】如何使用免费工具查找类加载器泄漏?【英文标题】:How to find classloader leak with free tools? 【发布时间】:2014-03-24 20:25:37 【问题描述】:

我正在调查 Tomcat/Spring/Hibernate 应用程序中的内存泄漏,它在几次重新部署后导致可怕的“out of permgen”错误。我已经下载了plumbr的免费版本,这证实了我有一个类加载器泄漏,但不幸的是我买不起499美元来获得详细的报告。是否有免费工具可以执行等效分析并告诉我在哪里寻找它?还是我可以调查的其他导致此类泄漏的常见原因?

到目前为止我已采取的步骤:

确保我的 JDBC 驱动程序在上下文关闭时未注册 手动关闭 mysql 驱动程序的 AbandonedConnectionCleanupThread(根据 Tomcat Guice/JDBC Memory Leak)

还有什么可能导致泄漏?

【问题讨论】:

作为对我自己问题的部分回答,这里有一个类加载器泄漏的常见原因的完整列表:java.jiderhamn.se/2012/02/26/… 你使用哪个版本的Tomcat? Tomcat 7.+ 确实支持 memleak 检测 我在 tomcat 7 上,并且已经修复了它可以检测到的所有泄漏,但其他地方仍在发生泄漏。 【参考方案1】:

您可以使用evaluation version of JProfiler 来调查类加载器泄漏。转到类加载器探测器,选择一个泄漏的类加载器并将它们显示在堆遍历器中,您可以在其中调查对类加载器加载的类的强引用。

有一个screen cast 向您展示了如何执行此操作。

免责声明:我公司开发 JProfiler。

【讨论】:

谢谢。它看起来像一个有用的工具,但在看到此响应之前我找到了另一种方法。【参考方案2】:

我发现 Eclipse 的内存分析工具运行良好。我将服务器设置为生成堆转储并使用 MAT(大致遵循指南here)来查找所有类加载器。似乎相关的是 org.apache.catalina.loader.WebappClassLoader,通过列出它们的 GC 根,我很容易发现我的问题是由 java.util.logging.Level 引起的,它是通过 org.jboss.logging.JDKLevel 间接引用的。

现在我只需要弄清楚如何防止 JBoss Logging 这样做...

【讨论】:

答案是确保它支持的日志记录目标之一存在于类路径中。我选择了 log4j,它只需要放入我的 WEB-INF/lib 目录。

以上是关于如何使用免费工具查找类加载器泄漏?的主要内容,如果未能解决你的问题,请参考以下文章

如何在源代码中查找内存泄漏

如何检查 C++ 代码中的内存泄漏。有没有检查内存泄漏的免费工具[重复]

追踪 .NET Windows 服务内存泄漏

泄漏金丝雀,Recyclerview 泄漏 mAdapter

查找从哪里加载 java 类

如何使用 Chrome 和 DevTools 查找影响页面性能的内存问题,包括内存泄漏内存膨胀和频繁的垃圾回收