背景:测试环境总发现某个项目cpu占用率偏高,有时动不动就挂了。
排查过程
1)找到最耗CPU的进程 top -c 输入P
image.png2)找到最耗CPU的线程 top -Hp pid 输入P
image.png3)将线程PID转化为16进制(堆栈里线程id是用16进制标识)
image.png转换工具:printf "%x\n" 14822=39e6
4)在堆栈里面找到Thread (pstack/jstack/grep)
jstack PID | grep "0x6b41" -C5
jstack 14815 | grep '39e6' -C5
image.png分析为GC线程导致
查看gc日志
jstat -gcutil 14815 2000 10
image.png可以看出 FullGc非常频繁 YGC 基本不动,算正常
查看代码得知,代码中有用hashmap做缓存,导致大对象直接进入老年代,导致Fullgc频繁
通过调整JVM参数解决(调整老年代大小,使其不再频繁Fullgc):
原:-Xmx4096m -Xms4096m -Xmn4096m -XX:PermSize=4096m
新:-Xmx4096m -Xms4096m -XX:NewRatio=8 -XX:PermSize=1096m
XX:NewRatio 表示年轻代占堆的比例,调整为八分之一,则老年代为八分之七
如果使用了 CMS 垃圾收集器,建议可以调整这个参数(调整到80%才进行Fullgc)
原:-XX:CMSInitiatingOccupancyFraction=70
新:-XX:CMSInitiatingOccupancyFraction=80
调整后 上线,压测后结果
image.png
网友评论