0%

YGC次数多时间长

一、现象

以完全相同的启动脚本(除了堆内存JVM参数之外,其他JVM参数未指定)运行完全相同的应用程序分别在A和B服务器上,A上JDK环境是OpenJDK 1.7,B上JDK环境是Oracle JDK 1.6,两应用程序的请求量也几乎相同,系统资源也可确保不是瓶颈所在。
通过JVM进程监控系统发现:A上的应用程序YGC次数多时间长。

二、诊断与解决

YGC跟年轻代相关,通过jstat -gccapacity JVM进程ID命令分别查看A和B上应用程序的相关容量值。
结果如下:

1
2
3
4
A上应用程序:

NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC PGCMN PGCMX PGC PC YGC FGC
1107520.0 1107520.0 1107520.0 110720.0 110720.0 886080.0 7281088.0 7281088.0 7281088.0 7281088.0 21248.0 169984.0 21248.0 21248.0 3805 0
1
2
3
4
B上应用程序:

NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC PGCMN PGCMX PGC PC YGC FGC
1398080.0 2796160.0 1398080.0 67008.0 65152.0 1265920.0 2796224.0 5592448.0 2796224.0 2796224.0 21248.0 86016.0 21248.0 21248.0 516 0

可发现:A上年轻代容量(1107520)小于B上年轻代容量(1398080),最主要的是A上“Eden/Survivor”比值(886080/110720约等于8)大大小于B上该比值(1265920/65152约等于19)。
A上“Eden/Survivor”比值接近于“SurvivorRatio”这个JVM参数的默认值,应该是由该JVM参数控制;B上“Eden/Survivor”比值应该不是由该JVM参数控制,而应该是经过动态调整得到的,故而可以定位到“UseAdaptiveSizePolicy”JVM参数。

通过jinfo -flag UseAdaptiveSizePolicy JVM进程ID命令,可发现A上如预期果然未开启“UseAdaptiveSizePolicy”JVM参数,B上如预期默认开启了“UseAdaptiveSizePolicy”JVM参数,这个差异很明显是不同JDK环境造成的

因此,具体解决方案有两个:

  • 统一JDK环境,将A上的OpenJDK 1.7改为Oracle JDK 1.6
  • A上应用程序手动开启“UseAdaptiveSizePolicy”JVM参数
您的支持将鼓励我继续分享!