java – JVM YoungGen 0%,Perm Gen 99%,OldGen Full

我有一个JEE应用程序,最近开始看到CPU使用率的峰值(例如,40核心服务器上的27个核心的100%)以及应用程序不可用的时间越来越长.它与下一篇文章中描述的问题非常相似,包括弹跳应用程序服务器使问题消失直到几小时后再次出现的事实:

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值?

在此先感谢您的任何帮助.

最佳答案

will the ~39GB of stuff in ParOldGen ultimately transition into PSPermGen?

Java 7中的PermGen(在Java 8中用metaspace替换)用于保存代码.从堆传递到PermGen的唯一事情是字节代码,因此除非您生成或加载类,否则任何东西都不会从一个传递到另一个.它们是不同的空间.

What is the significance of the nearly empty PSYoungGen space?

完整的GC后,年轻的一代是空的.一旦你的老一代开始填补,完整的GC就很常见了.

Does this mean that the application isn’t creating any/many new object instances at steady state?

它更可能意味着它最近已经完成GC-ed.

describes the option of “giving more headroom” to ParOldGen, but I’m not clear if that means increasing the total heap size via -Xmx or if there’s an explicit JVM GC parameter.

增加最大堆可以给你更大的空间,但我会首先检查

>你没有内存泄漏.
>你无法将大部分数据从堆中移出,例如数据库或本机内存.

Would the fact that the PSYoungGen is essentially empty mean that it’s too large, and that I should use a smaller NewRatio value?

这可能有助于为旧版本提供更多空间,但它可能会在内存耗尽之前给你更多时间.

点赞