前段时间有一次晚上系统版本升级,隔天回来后发现系统开始不稳定了,很多接口都报服务不可用,遂跟全组同事一起分析。
经排查,服务器上很多机器的CPU都飙的很高,内存使用量也一直降不下来,初步怀疑是哪里代码异常,导致堆栈内存居高不下,这种情况我们可以使用内存分析工具mat来分析程序的内存分布情况,mat是一个很简单的工具,在window下只要把生成的堆文件用mat打开就可以清晰的看到内存分布情况了。
windows版本
- 下载mat工具:http://www.eclipse.org/mat/downloads.php
- 先在cmd运行jps获取进程的pid,如7584
- 执行命令生成内存文件
jmap -dump:format=b,file=heap.bin 1345
- 在mat中打开就可以看到各种内存信息了
在Dominator Tree中按对象大小从上到下展示对象信息,可以很方便的定位那些占用大的对象
linux版本
因为生产环境一般都是linux的,而生产上的dump文件一般都是GB级别以上的,如果直接把生产的文件来到本地来分析,太耗费时间了,那么我们其实可以用linux版本的mat,直接在上面分析dump文件,生成的分析报告也就几个kb,再把报告拉到本地查看。
- 下载mat工具。
根据jdk版本下载对应的mat工具,我生产上的jdk是1.7的,所以下载的是1.7的mat
wget http://ftp.jaist.ac.jp/pub/eclipse/mat/1.7/rcp/MemoryAnalyzer-1.7.0.20170613-linux.gtk.x86_64.zip
解压后配置mat的内存大小,内存需大于dump文件,不然会报内存不足
vi MemoryAnalyzer.ini
-Xmx5024m
- 获取进程的内存转储文件。
先执行ps -ef|grep java获取进程的pid
再执行jmap -dump:format=b,file=heap.bin PID得到dump文件 - 生成分析报告。
在mat目录下执行./ParseHeapDump.sh heap.bin org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components
稍等片刻后会生成以下三个zip文件,这时候就可以拉到本地查看了
heap_Leak_Suspects.zip
heap_System_Overview.zip
heap_Top_Components.zip
- 在本地打开heap_Leak_Suspects.zip中的index.html文件。
可以看到有一个进程的内存占用已经达到3.4个G了
点击See stacktrace进去查看详细,看到这里有一个sql的查询,回头查看代码,发现这条SQL在版本升级是有同事不小心把where条件去掉了,导致了每次进来都是全表查询,而这张表的数据量已经是八千万级别了
至此,这次生产事故的内存已经分析顺利结束。
- 本文链接: https://www.acgclub.xyz/archives/1573974081544
- 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!