Java 对Permgen空间这种行为的解释

Java 对Permgen空间这种行为的解释,java,tomcat,memory,jvm,permgen,Java,Tomcat,Memory,Jvm,Permgen,我正在用两个独立的web应用程序来试验一些问题,它们在一个项目中相互协作。经过X次部署后,我得到了臭名昭著的“java.lang.OutOfMemoryError:PermGen space”错误 所以我用VisualVM监控PermGen空间有一段时间了,不断地重新部署应用程序,看看发生了什么 这里是奇怪的行为: 首先,我已经重新部署了超过15次的第一个应用程序。其行为正如预期的那样:内存图就像一个不断增加的阶梯,直到接近最大大小(67MB)。此时,内存被释放并返回到初始级别 当我重新部署第二

我正在用两个独立的web应用程序来试验一些问题,它们在一个项目中相互协作。经过X次部署后,我得到了臭名昭著的“java.lang.OutOfMemoryError:PermGen space”错误

所以我用VisualVM监控PermGen空间有一段时间了,不断地重新部署应用程序,看看发生了什么

这里是奇怪的行为:

首先,我已经重新部署了超过15次的第一个应用程序。其行为正如预期的那样:内存图就像一个不断增加的阶梯,直到接近最大大小(67MB)。此时,内存被释放并返回到初始级别

当我重新部署第二个应用程序时也是如此

然后我尝试同时重新部署这两个组件(tomcat按顺序执行),梯形图的“阶梯”更大,但行为与单个部署中相同

然后我做了最后一次测试。我同时重新部署了两个应用程序,直到内存接近极限,然后我只重新部署了其中一个应用程序。和。。瞧,PermGen错误

所以。。这里到底发生了什么

VisualVM的图表。前半部分(左)对应于单个部署(应用程序1和2)。下半部分(右)表示我超出限制并得到错误的点

谢谢大家!

OP在这里

我对此做了一些研究,我的结论是,要完全理解与permgen空间相关的JVM行为几乎是不可能的:)

在这一点上,我们都阅读了一些关于类加载器可能存在的内存泄漏的主题。类的定义保持未使用,但存储在内存中,直到超过permgen限制。这是理论。但是要真正了解这个漏洞的来源是非常困难的,我的意思是,我们的应用程序中是否存在由糟糕的编程导致的内存泄漏

最后,我解决这个问题的方法是增加内存大小并使用一些标志。这是我在stackoverflow中读到的一些相关主题。这是用户在发现permgen错误时所做的。我不确定这是一种解决办法还是仅仅是一种忘记痛苦的方法……;)

在Catalina.sh(TOMCAT)中,我添加了这一行:

export CATALINA_OPTS="-Xms64m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled"
其中:

-Xms64m将java堆内存的最小大小设置为64MB

-Xmx512m将java堆内存的最大大小设置为512MB

-XX:PermSize=128m将permgen内存的初始大小设置为128MB

-XX:MaxPermSize=512m将permgen内存的最大大小设置为512MB

-XX:+UseConcMarkSweepGC:jvm将使用并发标记清理垃圾收集器永久生成java堆


-XX:+CMSClassUnloadingEnabled:垃圾收集器将扫描PermGen并删除不再使用的类。

我注意到的主要问题是,无论如何,您都非常接近最大值。您应该增加最大perm大小。您使用的是哪个Tomcat/JVM?我使用的是ApacheTomcat 7.0.27,Java版本是“1.6.027”