我正在Glassfish 3.1上运行GWT + Hibernate应用程序。几个小时后,我跑出了Permgen空间。这没有任何webapp重新加载。我正在使用–XX:MaxPermSize=256m –XmX1024m
。
我接受了this page的建议,发现我泄漏了很多类 - 我的所有Hibernate模型和所有GWT RequestFactory代理。
上面引用的指南说“检查链条,找到意外参考,并修复代码”。说起来容易做起来难。
类加载器始终指向org.glassfish.web.loader.WebappClassLoader
的实例。进一步深入,我发现了$Proxy135
和类似命名对象的大量引用。但我不知道还有什么可以贯彻的。
答案 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。