有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

javaweb应用程序中的内存泄漏

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

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

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

enter image description here

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

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


共 (3) 个答案

  1. # 1 楼答案

    我不是Tomcat及其重新部署实现方面的专家,但在我们使用JBoss的时候,我们也遇到过类似的情况。这是因为PermGen空间不是垃圾收集的,每个新部署都会将类放在其中。 因此,如果您不在Java8上,请检查实际的“泄漏”是否不在permgen空间中

  2. # 3 楼答案

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

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