我有一个使用hibernate 3.6.4和spring 3.2.4(mvc,tx和安全性)的Web应用程序,并且在tomcat 7中运行。每次当我部署应用程序的较新版本而没有重新启动tomcat时,则使用tomcat增加了大约50MB。
我创建了一些堆转储,并使用Eclipse Memory Analyser分析了它们。我发现,每次重新部署应用程序时,都会创建一个新的WebappClassLoader实例。但是,即使在我使用tomcat管理器停止了应用程序之后,WebappClassLoader仍保留在内存中,并且不会进行垃圾收集。
因此,每次重新部署后,都会在内存中保留一个额外的WebappClassLoader并使用大约50MB的内存。
我使用Eclipse Memory Analyzer来查找从WebappClassLoader到GC根目录的引用路径。结果,我找不到任何强大的引用来阻止WebappClassLoaders的垃圾回收。
那么,什么使WebappClassLoaders保持活力?为了找出原因,我还可以在其他地方进行调查,是什么阻止了WebappClassLoader进行垃圾收集?
我以为可能有一个阻止finalize()的方法来阻止GC完成垃圾收集。但是我该如何检查呢?
最佳答案
从理论上讲,类加载器是在没有引用对象实例且不需要类卸载的情况下进行垃圾回收的,但实际上似乎存在更多问题。
我建议阅读这两篇文章
http://frankkieviet.blogspot.com.au/2006/10/classloader-leaks-dreaded-permgen-space.html
http://frankkieviet.blogspot.com.au/2006/10/how-to-fix-dreaded-permgen-space.html