Java堆溢出
java堆用于存储对象实例,我们只要不断的创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清楚这些对象,就会在对象数量达到堆的容量限制后产生内存溢出的异常
实例代码清单如下:
package com.kerry;
import java.util.ArrayList;
import java.util.List;
public class JvmTest {
static class OOMObject{}
public static void main(String args[]){
List<OOMObject> list = new ArrayList<JvmTest.OOMObject>();
while (true) {
list.add(new OOMObject());
}
}
}
图上代码运行配置限制java堆的大小为20MB ,不可动态扩展(将堆的最小值 -Xms参数与最大值-Xmx设置成一样即可避免自动扩展),通过参数-XX:HeapDumpOnOutOfMomeryError可以让虚拟机在出现内存溢出异常时Dump出当前内存堆转储快照以便时候分析
以上代码运行结果:
<span style="color:#ff0000">java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid7612.hprof ...
Heap dump file created [27972754 bytes in 0.089 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3210)
at java.util.Arrays.copyOf(Arrays.java:3181)
at java.util.ArrayList.grow(ArrayList.java:261)
at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
at java.util.ArrayList.add(ArrayList.java:458)
at com.kerry.JvmTest.main(JvmTest.java:14)</span>
Java堆内存的OOM异常是实际应用中最常见的内存溢出异常情况。出现Java堆内存溢出时候,异常堆栈信息java.lang.OutOfMemoryError
会跟着进一步提示 Java heap space,要解决这个区域的异常,一般手段是通过内存印象分析工具(如eclipse memory analyzer)对dump出来的堆
转储快照快照进行分析,重点是确认内存重点对象是否是必要 ,也就是要先分清楚到底是出现了内存泄漏还是内存溢出
上图是使用eclipse memory analyzer打开的堆转储快照文件