Mat内存溢出dump文件分析工具http://www.eclipse.org/mat/downloads.php
模拟OOM Java 程序
package org.cj.oom;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* 创建内存分析
* java启动参数指定内存 -Xms1m -Xmx1m
* @author chenjian
* @date 2022/11/18
* @version 1.0
*/
public class OomAnalysis {
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
List<OomAnalysis> list = new ArrayList<>();
while (true) {
list.add(new OomAnalysis());
}
}
}).start();
while (true) {
TimeUnit.SECONDS.sleep(3);
}
}
}
程序运行后会出现异常
获取Dump文件方式
1.主动方式获取dump文件
使用 jps命令查询堆出现异常的进程名
jps
使用命令获取dump文件到指定目录
jmap -dump:format=b,file=E:/test/headdump.hprof 14380
2.通过制定Java vm 参数方式获取(推荐使用)
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=E:/test/heapdump1.hprof
3.获得的文件如下图所示
DUMP 文件分析
1.打开Mat工具 MemoryAnalyzer.exe
2.点击File -> Open Heap Dump ,点击 Finish
3.点击切换视图
4.发现大部分内存占用的是这个线程,占用了92.66%
5.点开发现,内存空间是被一个 36万长度的数组给占据了,数组的元素是 OomAnalysis
6.接下来要寻找出现这个问题的代码在哪里。再返回到最初的大饼图,点击最下面的details。然后点击See stacktrace 堆叠追踪。
7.继续点击 Probblem Suspect 1详情中的 See stacktrace
8.这里可以看到完整的堆栈信息,里面可以发现我们增加模拟溢出代码的那个Java文件,并且爆发内存溢出的代码行也可以对上,至此溢出分析结束。
本文的内存分析针对性较强,实际情况 会有很多的干扰因素,我们需要从这些因素中找出真正的元凶。
可以配合 Jstat 命令来一起分析OOM的原因,缩小排查的范围。
jstat命令博客https://blog.csdn.net/maosijunzi/article/details/46049117?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-3-46049117-blog-124800644.pc_relevant_3mothn_strategy_and_data_recovery&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-3-46049117-blog-124800644.pc_relevant_3mothn_strategy_and_data_recovery&utm_relevant_index=4