双十一之前检查下服务,通过监控的GC日志发现我们有个订单的服务Young GC时间似乎有点过长,有很多都到达秒级别了。平时运行着其实还好也没出啥问题。但是考虑到双十一流量比较大,还是决定关注下这个问题。
我们用的是G1垃圾回收器,我印象中G1是可以配置最大停顿时间的,赶紧去上去容器平台(我们的服务是部署在K8S上的)看了一下,确认了是配置了这个最大时间的停顿目标。
-XX:MaxGCPauseMillis
我们都知道GC停顿时间(stop the world)是垃圾回收器的一个非常重要的指标。G1回收器有个自动调优的功能,它可以根据你设置的停顿目标(就是上面那个参数),尽最大努力不超过这个停顿时间。
但是从监控的现象来看,似乎G1没有尽力啊。
去官方文档查资料,在oracle官方关于G1的说明看到这样一句话:
Young Generation Size: Avoid explicitly setting young generation size with the -Xmn option or any or other related option such as -XX:NewRatio. Fixing the size of the young generation overrides the target pause-time goal.
大概解释下:G1回收器模式下,应该尽量避免配置-Xmn
,或者-XX:NewRatio
等固定年轻代的选项,因为这个配置会覆盖设置的停顿时间目标。
看来已经接近真相了,我感觉去检查了下服务的JVM配置,如下图所示:
果然有这个-Xmn
啊。因为我们的服务中间经历过从CMS到G1的升级,有可能是升级的时候,忘记去掉这个配置了。
于是在业务低峰时间,去掉这个配置,重启,再观察下监控。
哈哈,这个GC时间看着就舒服很多了。
问题解决了,我又可以愉快的摸鱼了。