记一次线上JVM内存占用率过高导致服务超时

某天中午突然商品模块发出告警邮件,报的超时,于是开始排查原因

1、去nacos看服务状态正常,没有挂掉

2、用top命令看cpu使用率正常

3、用jstat -gcutil {pid} 查看堆内存使用情况,发现了问题

 当时看到full gc次数是5,时间是2.13秒,感觉是full gc导致的服务超时(后面发现其实不是),于是使用jmap -dump命令把dump文件导出,并使用eclipse mat进行分析

 进入Doinator Tree可以按照对象大小排序

 进入后发现一个线程池对象占用了51%,而且是CompletableFuture的默认线程池,再深入就发现原来是在开启线程时往新线程中放入了一个大对象,由于商品又是访问量比较大的模块,就导致了多线程中大对象一直堆叠的情况

 优化方向就是不将大对象传入线程中,而是在只传对象id,在线程中查出需要的对象后再到主线程赋值。

但但但但!

当我优化好后重启服务,再使用jstat -gcutil查看他的内存使用情况,发现full gc还是有4次,我才发现事情并没有这么简单。

于是在服务启动脚本中添加-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/logs/gc.log,发现full gc原因只是启动时MetaspaceSize未设值默认是20M,但启动后Metaspace扩容了4次(MaxMetaspace扩容一次会触发一次full gc)。

这时去看-Xloggc:/logs/gc.log打印的gc日志可以查到full gc时MetaspaceSize最大扩容到多大,我们再在启动脚本中添加 -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m "。

重启后full gc次数为0,解决了full gc的问题。

最后

回过头来看服务超时原因应该是堆内存使用率过高导致的

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值