我正在尝试追踪我的 Web 应用程序中的内存泄漏,它导致 PermGen 空间填满并在几次重新加载后抛出 OutOfMemoryError: PermGen size。现在我知道我可以停止/启动整个 Tomcat 实例,但我正试图找出内存泄漏的原因。
我读过这篇文章 http://java.dzone.com/articles/memory-leak-protection-tomcat这表明我必须确保在停止我的应用程序后不应该有对 WebappClassLoader 的未完成引用,这将防止它被垃圾收集。使用 YourKit 和 Memory Analyzer,我发现了几个在第 3 方库中发生这种情况的情况并修复了它们。
我现在处于两个工具都报告没有“从 GC 根到对象 (WebappClassloader) 的路径”的地步,但 WebappClassloader 仍然没有被垃圾收集!以前有人遇到过这样的事情吗?
我正在使用 Tomcat 6.0.32
最佳答案
抱歉我没有早点解决这个问题...
我已经消除了 WebappClassloader 的所有 GC 根,但它只是没有被垃圾收集。我尝试强制垃圾回收,但无济于事。
问题是调用 Runtime.getRuntime().gc();
并不能保证所有可能的东西都会被垃圾回收——只是 JVM 会尽最大努力这样做。
在重新加载 Tomcat 几次之后,JVM 开始在 PermGen 空间上运行不足,WebappClassloader 确实被垃圾收集了。我假设 JVM 之前没有对它进行 GC,因为它不需要。
关于Tomcat WebappClassloader 未被垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6978871/