Glassfish / Hibernate的PermGen空间问题

时间:2011-04-01 05:08:15

标签: java memory-leaks classloader glassfish-3 permgen

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

我接受了this page的建议,发现我泄漏了很多类 - 我的所有Hibernate模型和所有GWT RequestFactory代理。

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

类加载器始终指向org.glassfish.web.loader.WebappClassLoader的实例。进一步深入,我发现了$Proxy135和类似命名对象的大量引用。但我不知道还有什么可以贯彻的。

4 个答案:

答案 0 :(得分:22)

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

-XX:+CMSPermGenSweepingEnabled

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

-XX:+CMSClassUnloadingEnabled

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

答案 1 :(得分:4)

有一些好的工具可以帮助解决这个问题,尽管你永远不会知道它。 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

答案 2 :(得分:4)

我通过迁移到Tomcat来解决这个问题。

答案 3 :(得分:2)

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

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

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

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

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