OOM内存溢出问题排查
问题复现
在Main
类中定义了一个大小为 1M 的字节数组buffer
。在main
方法中,创建了一个ArrayList
来存储Main
对象。
通过一个无限循环,不断向列表中添加Main
对象,直到发生内存溢出异常。
/**
* OOM溢出测试 -Xms16m -Xmx16m -XX:+HeapDumpOnOutOfMemoryError
* 说明:-Xms16m -Xmx16m 设置堆内存大小为16M,-XX:+HeapDumpOnOutOfMemoryError 当发生OOM时,自动生成dump文件
*/
public class Main {
// 初始化一个1M大小的数组
byte[] buffer = new byte[1024 * 1024];
public static void main(String[] args) {
List<Object> list = new ArrayList<>();
int count = 0;
try {
while (true) {
list.add(new Main());
count++;
}
} catch (Exception e) {
System.out.println("count = " + count);
e.printStackTrace();
}
}
}
添加启动参数:
通过设置-Xms16m -Xmx16m
参数,将堆内存大小设置为 16M;通过-XX:+HeapDumpOnOutOfMemoryError
参数,当发生 OOM 时,会自动生成 dump 文件,以便后续分析内存溢出的原因。
此时运行报错,并生成了一个dump文件:
问题分析
我们使用JProfile打开这个dump文件,也就是hprof后缀。
在运行中产生了实例数
产生的一些大对象:
可以看到就是因为我们不断的往这个List里面塞大数据,导致内存溢出
在现场转储中,可以看到是出现了什么问题,以及是哪一行有问题