记录一次jvm_old过高、频繁Full GC的完整解决过程

最近重构服务项目,已经上线了一个多月了,突然这两天收到服务监控报警短信显示jvm_old过高,然后经过一系列的排查定位到问题并解决的过程分享下。

监控短信

1、首先登录到所在服务机器top命令找出占用cpu最高的进程Id

查看占用cpu较高的进程

2、查看进程中占用cpu过高的线程Id

1451在线10进制转换16进制为5ab

3、使用jstack 1422[进程Id] > jstack_01打印堆栈信息,下载到本地,然后在文件里搜索线程id16进制的线程

可以发现是VM线程在gc

4、使用jstat -gcutil 1422[pid] 1000[毫秒数]打印gc信息

此图发现old区都已经接近100%
大概说一下,S0,S1这些参数代表的含义

到这里基本确定就是Full gc太频繁导致机器old区过高

5、确定问题了,现在要定位具体代码的问题,只能查看堆内存采用mat(Memory Analyzer tool)工具来分析

命令:jmap -dump:format=b,file=文件路径/dumpfile.hprof 1422

文件有八百多M,下载到本地

6、下载mat工具,下载链接地址:http://www.eclipse.org/mat/downloads.php

下载直接解压就可以

7、打开MemoryAnalyzer.exe,直接File > Open Heap dump > 选择下载的dump文件 


直接点击Leak Suspects

查看内存泄露的报告,点击Details 往下拉查看具体的线程

打开红框的线程
没办法截图用手机拍的

打开上图红框,再点击下图红框视角,可以得到如下图

点击红框视角

到这里基本确认是线程全部在创建esb消息,old区无法及时回收导致cpu过高。由于重构项目接口暂时还不多,马上就定位到了项目中的问题代码。问题代码为发送异步消息时每次重新创建发送对象,及时修复解决上线,再观察发现cpu占用恢复正常。需要总结的是写代码的时候一定要注意质量,而且需要快速定位问题才能保证服务的稳定性。

你可能感兴趣的:(记录一次jvm_old过高、频繁Full GC的完整解决过程)