JVM内存溢出与排错
一、JVM堆内存溢出
Java堆用于存储对象实例,我们只要不断创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制来清除这些对象,就会在对象数量达到最大队的容量限制后产生内存溢出异常。
代码:
/**
* Java堆内存溢出
* @author jiangtong
*
*/
public class HeapOOM {
static class OOMObject{
}
/**
* -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -XX:PermSize=32M -XX:MaxPermSize=64M -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
*/
public static void main(String[] args) {
List<OOMObject> list = new ArrayList<OOMObject>();
int count = 0;
while(true){
try {
count++;
list.add(new OOMObject());
System.out.println("共构造了"+count+"个对象");
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
虚拟机执行参数说明:
Xms20M -Xmx20M:最小堆内存和最大堆内存设置为一样是为了避免堆内存的自动扩展
-Xmn10M:新生代内存分配10M,剩余的交给老年代
-XX:SurvivorRatio=8:新生代中Eden区和Survivor区的内存比例为8:1
-XX:PermSize=32M:永久代最小内存32M
-XX:MaxPermSize=64M:永久代最大扩展内存64M
-XX:+HeapDumpOnOutOfMemoryError:堆内存溢出时Dump出当前的内存堆转储快照以便事后分析
1、控制台输出分析:
[GC [DefNew: 8192K->1024K(9216K), 0.0426563 secs] 8192K->4599K(19456K), 0.0427200 secs]
[GC [DefNew: 6237K->1024K(9216K), 0.0552875 secs] 9813K->9742K(19456K), 0.0553528 secs] [GC [DefNew: 7581K->7581K(9216K), 0.0000467 secs][Tenured: 8718K->10240K(10240K), 0.1228164 secs] 16299K->11923K(19456K), [Perm : 2086K->2086K(32768K)], 0.1229961 secs]
[Full GC [Tenured: 10240K->7996K(10240K), 0.1247832 secs] 19456K->15528K(19456K), [Perm : 2086K->2086K(32768K)], 0.1248966 secs]
[Full GC [Tenured: 8598K->8598K(10240K), 0.1296810 secs] 17814K->17814K(19456K), [Perm : 2086K->2086K(32768K)], 0.1297631 secs]
[Full GC [Tenured: 8598K->8595K(10240K), 0.1481811 secs] 17814K->17811K(19456K), [Perm : 2086K->2084K(32768K)], 0.1482582 secs]
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid3504.hprof ...
Heap dump file created [32580683 bytes in 1.553 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2760)
at java.util.Arrays.copyOf(Arrays.java:2734)
at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
at java.util.ArrayList.add(ArrayList.java:351)