1.首先我们要明确一点minor gc和full gc都还发送STW(所有运行jvm线程终止)
背景:
我们系统最近在做促销活动,之前一直正常运行,但是促销开始后,有用户反页面馈响应比较慢
排查:
1.通过jps命令发现cpu大概每隔5分钟左右会达到300%
2.通过jstat -gc pid 命令查看;果然在5分钟左右就会一次full gc ,且每次会释放大量空间(注意:这里是一个主要线索,说明很多临时垃圾进入老年代)
3.配置参数:
-Xms = 4g:堆内存初始大小
-Xmx = 4g: 堆内存最大允许大小
-Xns = 100m:年轻代内存初始大小 -XX:NewSize(-Xns)
-Xmn=100m :年轻代内存最大允许大小 -XX:MaxNewSize(-Xmn)
-XX:SurvivorRatio=8 年轻代中Eden区与Survivor区的容量比例值,默认为8,即8:1:1
4.通过上面配置参数分析可知:Eden=800m s0=s1=100m
主要分析思路:
1.分析我们的程序,每次请求大概生成12m的变量,并发大概10s/次,因此每秒生成120m的变量,也就是大概6s进行一次minor gc,
2.当进行minor gc过程中,可能存正在执行的线程还不能进行gc(root跟存在),就会移到s1区域,这时s1只有100m,放不下120m变量,因此进入老年代
3.老年代大概3g,每次120m,也就是大概进行30次*6s=180秒,老年代就满了,因此发生full gc,致使频繁full gc
解决:
调整Eden s0 s1大小
将s1 s0调整大于120,就可以了
结尾:
本次遇到的只是jvm其中一个问题,线上可能的jvm问题远远不止于此,因此需要我们掌握更多jvm调优知识