6

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

我从这个页面得到了建议,发现我泄露了大量的类——我所有的 Hibernate 模型和我所有的 GWT RequestFactory 代理。

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

类加载器总是指向一个org.glassfish.web.loader.WebappClassLoader. 进一步挖掘,我发现了很多来自$Proxy135和类似名称的对象的引用。但我不知道还有什么办法可以通过。

4

4 回答 4

22

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

-XX:+CMSPermGenSweepingEnabled

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

-XX:+CMSClassUnloadingEnabled

此设置告诉 PermGen 垃圾收集扫描对类对象采取操作。默认情况下,类对象获得豁免,即使在垃圾回收期间访问 PermGen 空间也是如此。

于 2011-04-01T05:25:12.073 回答
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

于 2011-06-26T11:17:38.380 回答
4

我通过迁移到 Tomcat “解决了”这个问题。

于 2012-10-21T01:44:07.297 回答
2

(我无法查看您提供的链接,因为它已被 websense 阻止,所以如果我要重述任何内容,我深表歉意)

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

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

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

一个很好的罪魁祸首是 JAXB,尤其是当您一遍又一遍地创建新的 JAXBContext 时。

于 2011-04-06T22:30:26.017 回答