6

我有一个使用 hibernate 3.6.4 和 spring 3.2.4(mvc、tx 和安全性)并在 tomcat 7 中运行的 Web 应用程序。每次我在不重新启动 tomcat 的情况下部署我的应用程序的新版本时,然后使用的内存tomcat 增加了大约 50MB。

我创建了一些堆转储并使用 Eclipse Memory Analyser 对其进行了分析。我发现每次重新部署应用程序时,都会创建一个新的 WebappClassLoader 实例。但即使在我使用 tomcat 管理器停止应用程序之后,WebappClassLoader 仍保留在内存中并且不会被垃圾收集。因此,每次重新部署后,都会在内存中保留一个额外的 WebappClassLoader 并使用大约 50MB 的内存。

我使用 Eclipse 内存分析器来查找从 WebappClassLoader 到 GC 根的引用路径。结果,我找不到任何可以阻止 WebappClassLoaders 被垃圾收集的强引用。

在此处输入图像描述

那么,是什么让 WebappClassLoaders 保持活力呢?我还能在哪里调查以找出阻止 WebappClassLoader 进行垃圾收集的原因?

我认为可能存在阻止 GC 完成垃圾收集的阻塞 finalize() 方法。但我怎么能检查这个?

4

3 回答 3

6

当没有对对象实例的引用并且不需要卸载类时,类加载器理论上会被垃圾收集,但实际上它似乎更有问题。

我建议阅读这两篇文章

http://frankkieviet.blogspot.com.au/2006/10/classloader-leaks-dreaded-permgen-space.html

http://frankkieviet.blogspot.com.au/2006/10/how-to-fix-dreaded-permgen-space.html

于 2015-11-24T16:02:06.243 回答
3

您也可以按照PermGen 内存泄漏剖析教程中介绍的步骤进行操作。他们正在使用Java Visual VM,但在 Eclipse Memory Analizer 中检查的步骤和内容也应该相同。在演示文稿中,您可以找到此类泄漏的可能原因。

另请注意,如果您没有看到任何提及WebappClassLoaders它可能是JVM有很多PermGen并且正在推迟驱逐。您可以通过以较小的PermGen大小运行并进行几次重新部署来轻松检查这一点。

于 2015-11-29T08:56:08.760 回答
0

我不是 Tomcat 方面的专家,它是重新部署实现,但是在我们使用 JBoss 的日子里,我们遇到了非常相似的情况。这是因为 PermGen 空间没有被垃圾收集,并且每个新部署都会将类放在那里。因此,如果您不在 Java 8 上,请检查实际的“泄漏”是否不在 permgen 空间中。

于 2015-11-27T11:31:28.897 回答