【发布时间】:2016-09-10 21:54:01
【问题描述】:
我有一个 JEE 应用程序最近开始出现 CPU 使用高峰(例如 40 核服务器上 100% 的 27 核),并且应用程序不可用的时间越来越长。这与以下帖子中描述的问题非常相似,包括弹跳应用程序服务器会使问题消失,直到它在几个小时后再次出现:
Old Gen heap is full and the Eden and Survivor are low and almost empty
当应用程序遇到这些“冻结”时,我获取了一些核心转储输出,我看到了以下 JVM GC 输出:
PSYoungGen total 11221504K, used 2435K
eden space 9238528K, 0% used
from space 19829796K, 0% used
to space 1970176K, 0% used
ParOldGen total 39613440K, used 39276477K
object space 39613440K, 99% used
PSPermGen total 254976K, used 115497K
object space 254976K, 45% used
根据引用的帖子和上述输出,我想我理解“冻结”是由在 ParOldGen 空间上运行的垃圾收集器(徒劳?)驱动的。我缺少的部分:
为什么 PermGen 空间的使用率保持在 45%。也就是说,ParOldGen 中约 39GB 的内容最终会转变为 PSPermGen 吗?
几乎空无一人的 PSYoungGen 空间有何意义?这是否意味着应用程序在稳定状态下没有创建任何/许多新对象实例?
上面的帖子还描述了为 ParOldGen“提供更多空间”的选项,但我不清楚这是否意味着通过 -Xmx 增加总堆大小,或者是否有明确的 JVM GC 参数。我看到NewRatio 参数控制年轻代相对于老一代的大小。 PSYoungGen 本质上是空的这一事实是否意味着它太大了,我应该使用较小的NewRatio 值?
提前感谢您的帮助。
【问题讨论】:
-
老一代的东西没有被提升到永久空间,你可能在永久空间的某个地方有泄漏,你的应用程序是否动态创建了很多类?
-
感谢您的评论。我现在明白 permgen 空间不是堆的一部分(每个 stackoverflow.com/questions/2129044/… )。该应用程序确实动态创建了很多类。看来我们要么有内存泄漏,要么应用程序的内存需求超过了当前的 -Xmx 值。
-
您动态创建了很多类或对象?如果是类,那么你的 permgen 会满,如果是对象,那么 oldgen。
-
那些类定义进入 PermGen 空间,如果你创建很多它们,你可能会达到 MaxPermSize 并且最终会出现缓慢和 OOM,再次查看数据,你的 permgen 没有调查麻烦区,这是你的老一代
-
OldGen 大约 40Gb 的堆空间 + YoungGen 大约 10Gb 的堆空间,这意味着您正在使用 50Gb 堆运行。这对我来说很重要。你能提供一些细节,为什么你需要这么多?无论如何,我认为首先你需要生成一个堆转储并使用 MAT 或其他任何东西对其进行分析。了解哪些对象正在占用您的堆,您是否真的需要在堆中使用它们,如果不需要,请了解为什么它们不是 GC-ed。
标签: java garbage-collection jvm heap-memory