最近重构服务项目,已经上线了一个多月了,突然这两天收到服务监控报警短信显示jvm_old过高,然后经过一系列的排查定位到问题并解决的过程分享下。
![](https://img.haomeiwen.com/i5217518/55146acd2d97376d.png)
1、首先登录到所在服务机器top命令找出占用cpu最高的进程Id
![](https://img.haomeiwen.com/i5217518/48cb9e48adde19e1.png)
2、查看进程中占用cpu过高的线程Id
![](https://img.haomeiwen.com/i5217518/02a937fdeeba5f26.png)
3、使用jstack 1422[进程Id] > jstack_01打印堆栈信息,下载到本地,然后在文件里搜索线程id16进制的线程
![](https://img.haomeiwen.com/i5217518/437decbdef40c221.png)
4、使用jstat -gcutil 1422[pid] 1000[毫秒数]打印gc信息
![](https://img.haomeiwen.com/i5217518/e4e44a5b05781a07.png)
![](https://img.haomeiwen.com/i5217518/b70a8846ca579de1.png)
到这里基本确定就是Full gc太频繁导致机器old区过高
5、确定问题了,现在要定位具体代码的问题,只能查看堆内存采用mat(Memory Analyzer tool)工具来分析
命令:jmap -dump:format=b,file=文件路径/dumpfile.hprof 1422
![](https://img.haomeiwen.com/i5217518/3ed4a5bfe170765f.png)
6、下载mat工具,下载链接地址:http://www.eclipse.org/mat/downloads.php
![](https://img.haomeiwen.com/i5217518/99eb1ca8a2735a17.png)
7、打开MemoryAnalyzer.exe,直接File > Open Heap dump > 选择下载的dump文件
![](https://img.haomeiwen.com/i5217518/196d45416d596d53.png)
查看内存泄露的报告,点击Details 往下拉查看具体的线程
![](https://img.haomeiwen.com/i5217518/ef94b824edcb8a2c.png)
![](https://img.haomeiwen.com/i5217518/512f85d3674bd26e.png)
打开上图红框,再点击下图红框视角,可以得到如下图
![](https://img.haomeiwen.com/i5217518/354e16d85b606061.png)
到这里基本确认是线程全部在创建esb消息,old区无法及时回收导致cpu过高。由于重构项目接口暂时还不多,马上就定位到了项目中的问题代码。问题代码为发送异步消息时每次重新创建发送对象,及时修复解决上线,再观察发现cpu占用恢复正常。需要总结的是写代码的时候一定要注意质量,而且需要快速定位问题才能保证服务的稳定性。
网友评论