记一次OOM排查优化实践

    技术2025-05-04  59

     

     工作中遇到了OOM问题需要排查,在此做一下分享,也做一下笔记

    这里模拟了工作中的OOM场景,实际代码就不拿出来了,以下是我自己写的代码

     

    定义一个无界队列,频繁往里面加入元素,代码如下,经测试,这是会产生OOM的

    /** * @author mengfh * * @version 2020-7-3上午9:15:52 * * @description OOM排查与优化 */ public class OptimizeOOM { public static void main(String[] args) { testQueue(); } private static void testQueue() { Queue<ArrayList<TestVO>> queue = new LinkedBlockingQueue<>(); for (int i = 0; i < 10000; i++) { ArrayList<TestVO> list = new ArrayList<>(); for (int j = 0; j < 1000; j++) { list.add(new TestVO()); } queue.add(list); } } }

     启动debug,让线程挂起,然后找到jdk/bin目录下的jconsole.exe,可以看到我们写的程序正在运行

     jconsole.exe里面有很多VM相关的东西,对于我们分析和学习还是有帮助的,具体如下,信息数量比较大

     既然要OOM,那我们就分析为什么OOM,这里配置一下VM参数,生成dump文件和文件地址

    -XX:+HeapDumpOnOutOfMemoryError    -XX:HeapDumpPath=D:/jad/heapdump.hprof

     

    要注意的是dump文件是比较大的,我本地随便跑一下就接近1G ,而我的最大堆内存是768M

    拿到了dump文件,那么就可以去分析dump文件哪里出问题了

    可以通过jdk自带的jhat来分析,也可以通过相关MAT来分析,如下是Eclipse Memory Analyzer 工具

    使用的话需要一定的基础,LZ一年工作经验,勉强能行,现在在逐步加强,具体使用可以去MAT官网

    另外,dump文件分析可以参考这篇文章https://blog.csdn.net/sheldon178/article/details/79543671

     

    除了jhat,jconsole和MAT以外,还有很多JDK自带的性能监控工具如:jps,jstack,jmap,jstat等等

    它们都在jdk/bin目录下,可以通过cmd运行 

    以下是理想的解决方案,思想是把无界队列变成有界队列,然后控制生产者生产的速度和消费者线程消费的速度

    OOM的产生原因很多,优化方案也很多,工作上的优化方案就不拿出来了,保密性高,怕出事

    路漫漫其修远兮,吾将上下而求索

    private static void testQueue() { Queue<ArrayList<TestVO>> queue = new LinkedBlockingQueue<>(100); for (int i = 0; i < 10000; i++) { ArrayList<TestVO> list = new ArrayList<>(); for (int j = 0; j < 1000; j++) { list.add(new TestVO()); } queue.add(list); //业务处理 //...... //这里假装是消费者线程在消费,当然还有很多方式,这是最简单的一种 queue.remove(); } }
    Processed: 0.010, SQL: 9