记一次生产环境的JVM优化历程

记一次生产环境的JVM优化历程

案发现场:

​ 在春节前的小年夜,我们的服务中有一个签到功能,这个功能主要是服务于集团内部员工(大概12W人),而且这些人会集中在一个非常短的时间段内进行签到,功能不复杂,但是一定会有高并发的场景出现。虽然签到功能在上线之前已经做过压测,但是大家都忽略了一个非常重要的地方,就是用户服务,大概在下午六点,并发上来之后,用户服务立马崩溃。恰好运维的同学刚好下班开车回家,在沃特法克…

抢救方案:

​ 下图是当时的PV访问统计,当时gateway没有做限流和熔断,中间空白的区域就是offline之后出现的短暂空白,当时的第一想法就是先加节点,先把服务跑起来,能够让用户使用。

image-20220217094023023

增加两个节点之后,服务总算是能够正产运行了,但是基本已经到八点了,高峰即将过去。

问题查找及优化:

First time:

​ 随后在查看那个时间段的JVM状态时,发现当时的FULL GC的频率非常高,差不多不到五分钟一次,而且GC Time都很长,随后我让运维的同学搞了一份在线的dump,但是看了半天没发现什么问题,没办法,只能把代码中不规范的地方优化一下,再次上线,虽然有效果,但是很有限,GC的频率低峰期下降到20分钟一次,高峰期仍然在10分钟一次,甚至更高。so,第一次优化宣告失败…

Second time:

​ 后来我找到运维的小伙伴,要求进入容器内部执行jstat命令看一下结果,重点来了,请看下图:

image-20220217100319276

经过分析发现,当时的JVM堆内存是3G,但是Eden和两个survivor加起来才10M,再次通过jmap确认一下

image-20220217100848607

查看jvm启动时候的参数,好家伙,运维的小伙伴自己添加了一个参数:-XX:MaxNewSize=10M

image-20220217101413520

HotSpot虚拟机默认的,新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ( 该值可以通过参数 –XX:NewRatio 来指定 ),即:新生代 ( Young ) = 1/3 的堆空间大小。老年代 ( Old ) = 2/3 的堆空间大小。其中,新生代 ( Young ) 被细分为 Eden 和 两个 Survivor 区域,这两个 Survivor 区域分别被命名为 from 和 to,以示区分。Eden : from : to = 8 : 1 : 1 ( 可以通过参数 –XX:SurvivorRatio 来设定 ),即: Eden = 8/10 的新生代空间大小,from = to = 1/10 的新生代空间大小。

-XX:MaxNewSize是设置jvm启动时新生代最大的内存,所以在高并发的场景中,必然存在大量的新生代对象,如果新生代内存设置为10M必然会出现高频率的YONG GC,而高频的Yong GC也会将大量的对象同步到老年代,进一步刺激老年代的GC,也就是FULL GC。

虚拟机给每个对象定义了一个对象年龄计数器,如果对象在Eden区出生并经过第一次Minor GC后仍然存活,并且能被SurvivorFrom区容纳的话,将被移动到SurvivorTo空间中,并将对象年龄Age设为1。对象在Survivor区中每熬过一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认是15岁)时,就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数-XX:MaxTenuringThreshold来设置。

到此问题已经明了,下面是我们将参数-XX:MaxNewSize删除,使用默认的分配比例,运行后的jvm状态。

下图是修改参数之前6个小时的FUGC频率及时间,高峰期基本不到十分钟一次,低峰期二十分钟一次。

image-20220216173226984

下图是经过一晚上的测试,jvm的内存状态及GC频率,效果很明显,前半部分是jvm参数调整之前的GC频率及内存状态,后半部分是调整之后的

image-20220217091122347

总结:jvm调优是一个细致的工作,不仅要求你有大量的知识储备,还要你能静下心,耐心的寻找蛛丝马迹,这个过程很痛苦,但是也让人乐此不疲,痛并快乐着。总有一天,那些你填过的坑,会引领你走向成功的路!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值