我正在使用Hibernate和glassfish服务器运行Java Web应用程序。我正进入(状态
多次部署后出现java.lang.OutOfMemoryError: PermGen space
异常。
我在我的环境变量中尝试了-XX:MaxPermSize=128M
,但是它不起作用。
最佳答案
这是类加载器内存泄漏。每次重新部署应用程序时,都会为其创建一个新的类加载器,并再次加载应用程序的所有类。这会消耗perm gen空间中的内存。
旧的类加载器及其所有已加载的类必须进行垃圾回收,否则,在多次部署之后,您最终将运行在PermGen空间OOME中。如果外部类加载器加载的对象持有对旧类加载器加载的任何对象的引用,则此方法不起作用。 This article很好地说明了问题。
通常,类加载器泄漏很难分析,有时很难修复。
要找出为什么不对旧的类加载器进行垃圾回收,您必须使用探查器。在JProfiler中,使用堆遍历器,选择glassfish类加载器对象,并使用传入的引用 View 检查到垃圾收集器根的路径。
该类加载器类称为org.apache.servlet.jasper.JasperLoader
。这是常规情况的屏幕截图,其中类加载器仅由已加载对象的实时实例保存。
在您的情况下,您应该看到来自外部对象的引用。 Web容器中类加载器泄漏的另一个常见原因是没有停止的后台线程。例如,谷歌Guice在3.0中存在此类错误。
(免责声明:我公司开发JProfiler)