6

当停止我的项目时,tomcat 说:

以下 Web 应用程序已停止(重新加载、取消部署),但它们之前运行的类仍加载到内存中,从而导致内存泄漏(使用分析器确认)。

我们在哪里发现哪些类留在内存中?

请帮我 。

4

2 回答 2

11

您可以运行jmap -histo它将显示您加载的类。

例如:

jmap -histo[:live] <pid>
    to connect to running process and print histogram of java object heap
    if the "live" suboption is specified, only count live objects

Example: jmap -dump:live,format=b,file=heap.bin <pid>

另一种方法是启用类加载调试信息并执行一些脚本来检测剩余加载的内容。

于 2012-05-25T14:28:58.837 回答
8

发生这种情况时,通常内存中有一些东西将 WebappClassLoader(负责为 webapp 实例加载类的类加载器)“固定”到内存中。如果您多次重新加载您的 web 应用程序,您将能够看到每次执行重新加载时 WebappClassLoader 实例的数量都会增加 1。这通常不是Tomcat 中的泄漏,而是直接在您的 web 应用程序代码中的泄漏、您使用的库中的泄漏,或者由一些执行愚蠢操作的特定 Java API 调用触发的泄漏。

首先,请阅读: http: //people.apache.org/~markt/presentations/2010-11-04-Memory-Leaks-60mins.pdf。这是对正在发生的事情的一个很好的描述。

其次,使用分析器来确定对 WebappClassLoader 加载的对象的引用。很多时候,只需使用 ServletContextListener 就可以在 webapp 停止时清理这些引用。

第三,如果您发现您使用的库有泄漏,请让他们知道。如果您发现来自 JRE 中的类的泄漏,请查看使用 JreMemoryLeakPreventionListener 的选项:http: //tomcat.apache.org/tomcat-6.0-doc/config/listeners.html#JRE_Memory_Leak_Prevention_Listener_-_org.apache .catalina.core.JreMemoryLeakPreventionListener。如果您找到的任何内容都没有选项,请前往 Tomcat 用户并告诉我们缺少的内容:我们将添加它。

于 2012-05-25T20:08:39.450 回答