记一次OOM排查优化实践

 

 工作中遇到了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();
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章