如何查找OOM根因

59 阅读1分钟

准备工作

我们新建一个spring boot应用 编写测试控制器

@RequestMapping(value = "/oomNoCatch", method = RequestMethod.GET)
@ResponseBody
public String oomNoCatch() {
    int i =0;
        List<Object> list = new ArrayList<>();
        while (true) {
            i++;
            list.add(new Object());
        }
}

上述代码可以快速产生大量对象并且不回收

设置初始化堆栈大小,这里设置小一点-Xms128m -Xmx256m ,可以快速打满内存

然后我们再启动命令增加

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=E:\

增加这个命令是为了出现OOM的时候进行日志打印

开始运行程序

image.png 当出现这个报错的时候,我们在E盘下可以看到有一份OOM日志文件输出

image.png 当出现这个问题的时候,说明已经模拟成功,接下来我们要对其进行日志分析。

MemoryAnalyzer

下载软件地址 eclipse.dev/mat/

因为下载的是最新版,只支持jdk17版本以上,所以我们需要修改一下jdk位置

image.png

我们修改 MemoryAnalyzer.ini 增加 -vm 你的路径/.jdks/corretto-17.0.8.1/bin/javaw.exe

开始分析

使用软件打开日志文件

image.png 我们看一下 Histogram (直方图)

image.png 这里可以看到我们创建的Object

这里需要进行分析,我们还可以看堆栈异常信息

image.png

image.png

这里即可定位真正产生OOM的位置~