JVM - 调优案例
2020-04-02 本文已影响0人
万福来
JVM - 调优案例
调优问题
线上的java应用,对陈功率和响应事件要求较高,经常出现成功率突然下降又自动恢复的情况。
image.png
JVM 基本配置
-Xmx22528m
-Xms22528m
-XX:NewRatio=2 # 年轻代和老年代的比例为1:2
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled # 降低标记停顿
JVM GC日志相关配置
-Xloggc:/data/gc.log
-XX:GCLogFileSize=10M
-XX:NumberOfGCLogFiles=10
-XX:+UseGCLogFileRotation
-XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
-XX:+DisableExplicitGC
-verbose:gc
CMS-Remark之前强制进行年轻代的GC
通过GC日志和成功率下降的时间点进行比对发现并不是每一次老年代GC都会导致成功率的下降,但是从中发现了一个规律:
image.png
前两次GC CMS-Remark过程在4s左右造成了成功率的下降,但是第三次GC并没有对成功率造成明显的影响,CMS-Remark只有0.18s。Java HTTP 服务是通过Nginx进行反向代理的,nginx设置的超时时间是3s,所以如果GC卡顿在3s以内就不会对成功率造成太大的影响。
image.png
在文档和相关资料中没有找到蓝色部分的含义,猜测是remark处理的内存量,处理的越多就越慢。添加下面两个参数强制在remark阶段和FULL GC阶段之前先在进行一次年轻代的GC,这样需要进行处理的内存量就
-XX:+ScavengeBeforeFullGC
-XX:+CMSScavengeBeforeRemark
备注:
1、蓝色部分的含义:remark标记需要清理对象的容量。
2、FULL GC阶段之前先在进行一次年轻代的GC的意义是:Yong区对象引用了Old区的对象,如果在Old区进行清理之前不进行Yong区清理,就会导致Old区被Yong区引用的对象无法释放。
结论
- 在CMS-remark阶段需要对堆中所有的内存对象进行处理,如果在这个阶段之前强制执行一次年轻代的GC会大量减少remark需要处理的内存数量,进而降低JVM卡顿对成功率的影响。
- 对于Java HTTP服务,JVM的卡顿时间应该小于HTTP客户端的调用超时时间,否则JVM卡顿会对成功率造成影响。