Glassfish / Hibernate的PermGen空间问题

我正在Glassfish 3.1上运行GWT + Hibernate应用程序。 几个小时后,我跑出了Permgen空间。 这没有任何webapp重新加载。 我正在运行–XX:MaxPermSize=256m –XmX1024m

我接受了这个页面的建议,发现我泄漏了很多类 – 我的所有Hibernate模型和所有GWT RequestFactory代理。

上面引用的指南说“检查链条,找到意外参考,并修复代码”。 说起来容易做起来难。

类加载器始终指向org.glassfish.web.loader.WebappClassLoader的实例。 进一步深入,我发现了许多来自$Proxy135和类似命名对象的引用。 但我不知道怎么回事。

新的类对象被放入PermGen,因此占用了越来越多的空间。 无论你制作PermGen空间有多大,它都将在经过足够的部署后不可避免地达到顶峰。 你需要做的是采取措施冲洗PermGen,以便你可以稳定它的大小。 有两个JVM标志可以处理这种清理:

 -XX:+CMSPermGenSweepingEnabled 

此设置包括垃圾收集运行中的PermGen。 默认情况下,PermGen空间永远不会包含在垃圾收集中(因此无限制地增长)。

 -XX:+CMSClassUnloadingEnabled 

此设置告诉PermGen垃圾收集扫描对类对象执行操作。 默认情况下,即使在garabage集合期间访问PermGen空间时,类对象也会获得免除。

有一些好的工具可以帮助解决这个问题,尽管你永远不会知道它。 JDK(1.6 u1及更高版本)附带了jhat和jmap。 这些工具将有很大帮助,特别是如果您使用jhat JavaScript查询支持。

看到:

http://blog.ringerc.id.au/2011/06/java-ee-application-servers-learning.html

http://blogs.oracle.com/fkieviet/entry/classloader_leaks_the_dreaded_java

http://www.mhaller.de/archives/140-Memory-leaks-et-alii.html

http://blogs.oracle.com/sundararajan/entry/jhat_s_javascript_interface

我通过移动到Tomcat来“解决”这个问题。

(我无法查看您提供的链接,因为它被websense阻止,所以如果我正在重述任何我道歉的事情)

听起来你有一个类加载器泄漏。 这些很难跟踪,将这些选项添加到实例配置中的JVM选项

 -XX:+PrintGCDetails -XX:+TraceClassUnloading -XX:+TraceClassLoading 

现在,当您运行应用程序时,您可以查看位于domain / logs文件夹中的jvm.log,查看正在加载和卸载的内容。 很可能,你会看到相同的类一次又一次地加载。

一个很好的罪魁祸首是JAXB,特别是如果你一遍又一遍地创建一个新的JAXBContext。