Skip to content
Go back

OOM实践及相应的排查方案

Published:  at  03:29 PM

OOM实践及相应的排查方案

prerequisite

使用到的工具备注
GCViewer用于分析gc日志
MAT用于分析堆转储文件

造成 OOM 的典型代码和排查方案(事前型的方案)

无限往List添加对象(堆溢出)

public class OomDemoApplication {

    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>();
        while (true) {
            list.add(new byte[1024 * 1024]); // 每次1MB
        }
    }

}

方案

  1. 配置OOM时转储堆文件 img.png 配置的jvm options参数:
-Xms1024m
-Xmx2048m
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/home/nbk/var/log/
-Xloggc:/home/nbk/var/log/gc.log
  1. 运行后抛出OOM异常,并生成堆转储文件和gc日志文件 OOM异常 img_1.png 堆转储文件*.hprof 和 gc日志文件gc.log img_2.png
  2. 使用GCViewer分析gc日志文件
 java -jar ./gcviewer-1.36.jar  

打开刚刚生成的gc.log文件 img_3.png 丢给AI帮我们分析一下: img_4.png 类似的不懂的指标都可以给AI,帮我们分析(多用几个AI,互相验证,防止幻觉) 分析结果: img_5.png img_6.png Click the link to view conversation with Kimi AI Assistant https://www.kimi.com/share/19c9d675-a9d2-86ba-8000-00006a3a5b8d

可能很多人想要把AI生成的表格一键导出出来,我做了个油猴脚本,比较简陋,朋友们可以试试:表格一键导出

  1. 使用MAT分析堆转储文件
./mat/MemoryAnalyzer

可以直接看LeakSupport分析报告 img_7.png mat比较容易的就找到了问题所在: img_8.png

The memory is accumulated in one instance of java.lang.Object[], loaded by <system class loader>, which occupies 1,072,714,568 (99.91%) bytes.

看dominator tree里更加清晰 img_9.png 有大数组对象一直没有释放,已经没有内存了,在怎么FGC也没有用了……

造成 OOM 的典型代码和排查方案(事中型的方案)

  1. 内存泄漏 - 静态集合持有引用
public class Cache {
    private static Map<String, Object> map = new HashMap<>();
    public static void add(String key, Object value) {
        map.put(key, value); // 永不释放
    }

    public static void main(String[] args) throws InterruptedException {
        while (true) {
            add(UUID.randomUUID().toString(), new Object[1024 * 1024]);
            TimeUnit.SECONDS.sleep(1);
        }
    }
}
  1. jps命令查看应用进程id
jps -l
  1. jmap命令查看各代内存分布
jhsdb jmap --heap --pid 12001  

img_10.png 4. 实时GC监控

jstat -gcutil 12001 1000 5
## 每1s输出一次gc情况,累计5次

img_11.png 5. jmap手动dump出堆情况

jmap -dump:format=b,file=dump.hprof 12001

然后打开MAT工具像上文一样进行分析 img_12.png 发现是HashMap对象消耗掉了所有的内存


Suggest Changes

Next Post
Spring多数据源事务配置与回滚测试实战