8

我有一个非常简单的“Hello world”类型的 Web 应用程序(Spring 3.2.1,Hibernate 4.1.9),用于停止/重新启动 Web 应用程序 Tomcat 7.0.26

The following web applications were stopped (reloaded, undeployed), but their
classes from previous runs are still loaded in memory, thus causing a memory
leak (use a profiler to confirm):
/myapp

我采取了以下步骤: 启动 JVisualVM 右键单击​​ Tomcat 并选择“堆转储”单击 [heapdump] 上的“OQL 控制台”运行此查询:

select x from org.apache.catalina.loader.WebappClassLoader x

找到 4 个实例:

org.apache.catalina.loader.WebappClassLoader

选择一个“started”字段为“false”的项目 右键单击​​“this”引用并单击“Show Nearest GC Root” 显示“未找到 GC root”对话框。

我错过了什么?任何帮助将不胜感激。谢谢。

4

2 回答 2

7

随着网络上的所有教程,显示您描述的确切过程,

  1. 使用 VisualVM,
  2. 搜索 WebappClassLoader,
  3. 寻找“开始”等于假的那些。
  4. 单击“显示最近的 GC 根”

当它返回“No GC Root”时可能会令人困惑。

但这是一件好事

这些教程错过了一步,查看 WebappClassLoader 列表时,单击右侧的“计算保留大小”链接

visualVM 显示计算保留大小的链接

稍后(取决于堆的总大小),这将显示如下内容

visualVM 显示保留的大小

Retained 值为 0 的行也是状态为 false 且没有 GC Root 的 ClassLoader。

这仅意味着它们已为 JVM 运行的下一次 GC 运行做好准备。

摘要:即使'tomcat泄漏检测'显示泄漏,如果保留大小为0,它还没有泄漏,它只是在等待GC将其删除。

注意:在 visualVM 中触发 GC 并不总是会删除它。虽然它会被 JVM 本身触发的 GC 移除。

于 2014-10-05T10:37:09.580 回答
-4

尝试从任务管理器进程中关闭 javaw.exe。

于 2014-05-06T14:25:56.580 回答