Java JVM YoungGen 0%、Perm Gen 99%、OldGen Full
我有一个JEE应用程序,它最近开始看到CPU使用率的峰值(例如,40核服务器上27个核的100%),并且应用程序不可用的时间越来越长。它的行为与下文中描述的问题非常相似,包括这样一个事实:反弹应用程序服务器会使问题消失,直到几个小时后再次出现: 我在应用程序遇到这些“冻结”时获取了一些核心转储输出,我看到了以下JVM GC输出:Java JVM YoungGen 0%、Perm Gen 99%、OldGen Full,java,garbage-collection,jvm,heap-memory,Java,Garbage Collection,Jvm,Heap Memory,我有一个JEE应用程序,它最近开始看到CPU使用率的峰值(例如,40核服务器上27个核的100%),并且应用程序不可用的时间越来越长。它的行为与下文中描述的问题非常相似,包括这样一个事实:反弹应用程序服务器会使问题消失,直到几个小时后再次出现: 我在应用程序遇到这些“冻结”时获取了一些核心转储输出,我看到了以下JVM GC输出: PSYoungGen total 11221504K, used 2435K eden space 9238528K, 0% used from space 1982
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空间上运行的垃圾收集器驱动的(徒劳?)。我缺少的部分是:
NewRatio
参数控制年轻一代相对于老一代的大小。PSYoungGen本质上是空的这一事实是否意味着它太大了,我应该使用更小的NewRatio
值
提前感谢您的帮助
ParOldGen中的~39GB容量最终会转变为PSPermGen吗
Java7中的PermGen(在Java8中被metaspace替换)用于保存代码。从堆传递到PermGen的唯一内容是字节码,因此,除非生成或加载类,否则任何内容都不会从一个传递到另一个。它们是不同的空间
几乎空无一人的PSYoungGen空间有什么意义
完成GC后,年轻的gen是空的。一旦你的老一代开始填满,完整的地面军事系统是很常见的
这是否意味着应用程序不会在稳定状态下创建任何/许多新对象实例
这更可能意味着它最近已经完成了GC-ed
描述了ParOldGen的“增加净空”选项,但我不清楚这是否意味着通过-Xmx增加总堆大小,或者是否有显式的JVM GC参数
增加最大堆可以给你更多的头部空间,但我会先检查一下
- 你没有内存泄漏
- 您不能将大量数据移出堆,例如数据库或本机内存
OldGen
和PermGen
空间不能共享PSPermGen
主要包含PermGen空间中的类加载器加载的类ParOldGen
包含长寿命对象的堆内存
在JDK1.8中,PermGen已被Metaspace取代。有关更多详细信息,请参阅此
有关更多详细信息,请参阅以下SE问题:
几乎空无一人的PSYoungGen空间有什么意义?这是否意味着应用程序不会在稳定状态下创建任何/许多新对象实例
@彼得·劳里的回答是正确的。完全GC后,YoungGen几乎为空=>您没有从应用程序中的短期对象中积累垃圾
上面的帖子还描述了ParOldGen的“增加净空”选项,但我不清楚这是否意味着通过-Xmx增加总堆大小,或者是否有显式的JVM GC参数
旧版本已满意味着您的应用程序将保留长寿命对象的堆
现在,您必须使用诸如或之类的分析工具来检查应用程序中可能存在的内存泄漏(如果有)
如果没有内存泄漏,可以使用-Xmx
增加堆大小
PSYoungGen本质上是空的这一事实是否意味着它太大了,我应该使用更小的NewRatio值
因为您使用的是更大的堆,所以我建议您使用G1GC算法。如果使用G1GC算法,不要自定义默认值,因为G1GC算法可以更好地管理堆
查看oracle关于交换机的文章(G1 GC交换机的完整列表
部分)、文章和相关SE问题:
旧版本的东西没有升级到permgn空间,你可能在permgen的某个地方有漏洞,你的应用程序是否动态创建了很多类?谢谢你的评论。我现在了解到permgen空间不是堆(per)的一部分。该应用程序确实动态创建了很多类。看起来我们要么内存泄漏,要么应用程序的内存需求超过了当前的-Xmx值。你动态创建了很多类或对象吗?如果类,那么你的permgen将满,如果对象,那么oldgen。这些类定义将进入permgen空间,如果你创建了很多类,那么你很可能会达到MaxPermSize,因此速度和OOM最终,再次查看数据,你的permgen不会进入问题区域,这是您的旧GenalOldGen的最大40Gb堆空间+YoungGen的大约10Gb堆空间,这意味着您正在使用50Gb堆运行。这对我来说很重要。你能提供一些细节吗?为什么你需要这么多?无论如何,我认为首先需要生成一个堆转储,并使用MAT或其他任何工具对其进行分析。了解什么是eati对象