java.lang.OutOfMemoryError:Web应用程序使用的PermGen空间

时间:2011-02-21 12:40:17

标签: java jsf memory-leaks icefaces permgen

我正在努力解决最近出现的outOfMemory PermGen问题。出现错误时保存的其中一个日志片段:

java.lang.OutOfMemoryError: PermGen space
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
        at org.apache.felix.framework.ModuleImpl$ModuleClassLoader.findClass(ModuleImpl.java:1872)
        at org.apache.felix.framework.ModuleImpl.findClassOrResourceByDelegation(ModuleImpl.java:720)
        at org.apache.felix.framework.ModuleImpl.access$300(ModuleImpl.java:73)
        at org.apache.felix.framework.ModuleImpl$ModuleClassLoader.loadClass(ModuleImpl.java:1733)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)

我增加了最大烫发大小-XX:MaxPermGen=128m,但这只是一个临时解决方案,因为我很确定我们在这里面临一些内存泄漏。我们的应用程序的Web部分部署在jetty(jsf + icefaces)上。单击随机组件会增加使用的内存 - 我使用jstat -gcold监视它,几乎每次命中都会增加3-4kb。我已将-XX:+TraceClassLoading添加到jvm params,当Web用户界面上有任何操作时,会看到许多sun.reflect.GeneratedConstructorAccessorsun.reflect.GeneratedMethodAccessor被记录。当使用99%的permgen时,我也进行了堆转储。我使用YourKit分析器来分析堆。在类加载器选项卡中,有一些sun.reflect.DelegatingClassLoader行,每行有1个类。什么可能导致记忆不断增长?任何帮助都将非常感激。

提前谢谢, 卢卡斯

5 个答案:

答案 0 :(得分:5)

在Sun JVM上,最初通过将JNI调用到JVM实现中来执行对属性和方法的反射访问。如果JVM注意到反射大量访问方法或字段,它将生成字节码以执行相同的操作 - 它称之为“通胀”的机制。这有一个初始速度命中,但在此之后运行速度快20倍。如果你做了很多反思,这是一个很大的胜利。

该字节码存在于DelegatingClassLoader实例创建的类中并占用permgen空间。如果这是一个问题,您可以通过将系统属性sun.reflect.inflationThreshold设置为0(零)来关闭通胀。

答案 1 :(得分:4)

首先,这与JSF没有特别的关系。与webapp的需求相比,你只是给你的appserver太少的内存。你会遇到同样的问题,每个其他框架都使用了很好的反射镜头(想想所有那些EL解析)。这可以是JSF,Wicket,Spring-MVC甚至是普通的JSP / Servlet。在基于组件的Web框架上,机会只会更大,这些框架严重依赖于EL解析器,例如JSF(和其他)。

此外,众所周知,当您(热)重新部署时,Tomcat(基于)服务器也可能导致这种情况。通过以下链接了解它以及如何处理它:

答案 2 :(得分:3)

我建议您使用Eclipse MAT并关注this tutorial dedicated to permgen problems

虽然duffymo注意到你在分析这个问题方面做得很好,但问题的根源似乎仍然未知。也许它只是其中一个组件,一些解析器(如jwenting建议的)或类似的。问题并不一定意味着你需要从堆栈中丢弃JSF。

答案 3 :(得分:1)

首先,感谢你做了如此彻底的调查工作,并且更好地写了你的问题。如果每个人都像你一样有才华和善于作家,世界(和这个网站)将是一个更好的地方。

我认为你已经找到了答案:我认为JSF及其反射的使用是你的问题。

这就是为什么我像瘟疫一样避免使用JSF的原因之一。

在我看来,JSF是Struts的失败扩展。我认为HTML / CSS / JavaScript / AJAX UI与JSF一样强大,如果不是这样的话,对我的JVM的负担要小得多。 UI调用服务并保持良好并与服务器端分离。

答案 4 :(得分:0)

Permgen问题通常是由一些进程执行很多String.intern()操作引起的。 一些XML / HTML生成器和解析器对此有所了解。 先看看那里,你可能很快就会遇到罪魁祸首。