我有一个非常简单的“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
所选的“开始”字段为“假” 右键单击“this”引用,然后单击“显示最近的 GC Root” 将显示一个对话框,显示“未找到 GC 根”。
我错过了什么?任何帮助将不胜感激。 谢谢。
最佳答案
网络上有所有教程,显示您所描述的确切过程,
- 使用 VisualVM,
- 搜索WebappClassLoader,
- 查找“started”等于 false 的内容。
- 点击“显示最近的 GC 根”
当它返回“No GC Root”时,可能会令人困惑。
但这是一件好事
这些教程遗漏了一个步骤,在查看 WebappClassLoader 列表时,单击右侧的“计算保留大小”链接
稍后(取决于堆的总大小),这将显示如下内容
Retained 值为 0 的行也是状态为 false 且没有 GC Root 的 ClassLoader。
这仅意味着它们已准备好进行 JVM 运行的下一次 GC。
总结:即使“tomcat泄漏检测”显示泄漏,但如果保留大小为0,则没有泄漏,只是等待GC将其删除。
注意:在 VisualVM 中触发 GC 并不总是会删除它。虽然它会被JVM本身触发的GC移除。
关于tomcat7 - permgen,但 Java VisualVM 说 "No GC root found",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17096112/