Permgen空间的这种行为的解释

我正在尝试使用2个独立的网络应用程序在项目中相互协作的问题。 经过X次部署后,我得到臭名昭着的“java.lang.OutOfMemoryError:PermGen空间”错误。

因此,我一直在用VisualVM监视PermGen空间一段时间,不断重新部署应用程序,以了解发生了什么。

而这里奇怪的行为:

首先,我已经重新部署了第一个应用程序的15倍以上。 行为如预期:内存图像一个不断增加的梯子,直到它接近最大尺寸(67MB)。 在这一点上,内存被释放并返回到初始级别。

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

然后我试着同时重新部署两者(tomcat按顺序执行此操作),并且梯子的“步骤”的大小更大,但行为与单个部署中的相同。

然后我做了最后一次测试。 我同时重新部署了两个应用程序,直到内存非常接近极限,然后我只重新部署了其中一个应用程序。 并且..voilà:PermGen错误。

那么......这里发生了什么?

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

在这里输入图像描述

谢谢!


OP在这里。

我一直在做这方面的研究,我的结论是,或多或少地不可能完全理解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,将最大内存大小设置为512MB。

-XX:+ UseConcMarkSweepGC :jvm将使用并发标记扫描垃圾收集器来处理Java堆的终身代

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

链接地址: http://www.djcxy.com/p/54993.html

上一篇: Explanation for this behaviour of Permgen space

下一篇: java.lang.OutOfMemoryError: PermGen space on web app usage