2011-10-07 260 views
30

我正在运行使用Hibernate和glassfish服务器的Java Web应用程序。我得到PermGen空间错误 - Glassfish服务器

java.lang.OutOfMemoryError: PermGen space例外,当我部署它几次。我试过-XX:MaxPermSize=128M在我的环境变量,但它不起作用。

+0

这是你在找什么:http://stackoverflow.com/questions/1996088/java-class-permgen-memory-leak-web-applications-generic-solution – Raedwald

回答

37

这是类加载器的内存泄漏。每次重新部署应用程序时,都会为其创建一个新的类加载器,并且您的应用程序的所有类都会再次加载。这会消耗perm gen空间中的内存。

旧的类加载器及其所有加载的类必须进行垃圾回收,否则在部署多次后最终会运行到PermGen空间OOME。如果由外部类加载器加载的对象持有对由旧类加载器加载的任何对象的引用,则这不起作用。 This article给出了一个很好的解释。

一般来说,类加载器泄漏难以分析,有时难以修复。 要找出为什么旧的类加载器不是垃圾收集,您必须使用一个分析器。在JProfiler中,使用heap walker,选择glassfish类加载器对象并使用传入引用视图来检查垃圾收集器根的路径。

类加载器类被称为org.apache.servlet.jasper.JasperLoader。下面是常规情况的屏幕截图,其中类加载器仅由加载对象的活动实例持有。

enter image description here

在你的情况,你应该看到从外部对象的引用。 Web容器中的类加载器泄漏的另一个常见原因是未停止的后台线程。例如Google Guice在3.0中有这样的错误。

(免责声明:我公司开发的JProfiler)

46

为了解决这个问题(在基于Linux的操作系统)就以下

1)增加内存(使这一问题不经常来)由配置“域。XML”在

/的glassfish /域/域1 /配置

搜索

<jvm-options>-XX:MaxPermSize=

set it to higher value eg- 198m or 256m

2)杀死了GlassFish过程以释放在其上正在运行的端口(在我的情况下,它是8686) 开放终端(在基于Linux的操作系统)和类型 -

sudo netstat -npl | grep 8686

这将导致类似..

tcp6 0 0 :::8686 :::* LISTEN 3452/java

下次使用

kill -9 3452杀死(在这种情况下,3452),该过程

现在尝试启动玻璃鱼,它应该开始。

+0

谢谢先生!很好! –

9

如果您使用的是Windows,请尝试使用任务管理器终止glassfish进程(java.exe * 32),然后重新启动服务器。

+0

这是完美的 –