jvm内存管理之java堆溢出 -实例分析

java堆用于存储对象实例,我们只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清楚这些对象,就会在对象数量达到最大堆的容量限制后产生内存溢出异常。

下面给出例子代码体验一下java堆溢出的过程:

1.通过jvm参数(-Xms20M -Xmx20M -Xmn10M ),限制java 堆的大小

2.通过jvm参数(-verbose:gc -XX:+PrintGCDetails )打印GC的过程信息

3.通过jvm参数(-XX:+HeapDumpOnOutOfMemoryError),可以让虚拟机在出现内存溢出异常时Dump出当前的内存堆转储快照。

[java] view plain copy
  1. package com.jaynol.jvm.oom.sample;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. /** 
  7.  * VM Args: 
  8.  *  -verbose:gc -XX:+PrintGCDetails  
  9.  *  -Xms20M -Xmx20M -Xmn10M -XX:+HeapDumpOnOutOfMemoryError 
  10.  * @author Johnny 
  11.  * 
  12.  */  
  13. public class HeapOOM {  
  14.   
  15.     static class OOMObject{}  
  16.       
  17.     /** 
  18.      * @param args 
  19.      */  
  20.     public static void main(String[] args) {  
  21.         List<OOMObject> list = new ArrayList<OOMObject>();  
  22.           
  23.         while(true){  
  24.             list.add(new OOMObject());  
  25.         }  
  26.     }  
  27.   
  28. }  
运行结果:

[GC [DefNew: 7669K->1024K(9216K), 0.0146870 secs] 7669K->4602K(19456K), 0.0147209 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
[GC [DefNew: 9216K->1024K(9216K), 0.0200416 secs] 12794K->10520K(19456K), 0.0200646 secs] [Times: user=0.03 sys=0.00, real=0.02 secs] 
[GC [DefNew: 9216K->9216K(9216K), 0.0000159 secs][Tenured: 9496K->5712K(10240K), 0.0564110 secs] 18712K->14138K(19456K), [Perm : 166K->166K(12288K)], 0.0564723 secs] [Times: user=0.06 sys=0.00, real=0.06 secs] 
[Full GC [Tenured: 5712K->5712K(10240K), 0.0396698 secs] 14625K->14625K(19456K), [Perm : 166K->166K(12288K)], 0.0396968 secs] [Times: user=0.05 sys=0.00, real=0.04 secs] 
[Full GC [Tenured: 5712K->5700K(10240K), 0.0441324 secs] 14625K->14612K(19456K), [Perm : 166K->166K(12288K)], 0.0441718 secs] [Times: user=0.05 sys=0.00, real=0.04 secs] 
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid1340.hprof ...
Heap dump file created [29756494 bytes in 0.462 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.util.Arrays.copyOf(Unknown Source)
at java.util.ArrayList.grow(Unknown Source)
at java.util.ArrayList.ensureCapacityInternal(Unknown Source)
at java.util.ArrayList.add(Unknown Source)
at com.jaynol.jvm.oom.sample.HeapOOM.main(HeapOOM.java:24)
Heap
 def new generation   total 9216K, used 8920K [0x33210000, 0x33c10000, 0x33c10000)
  eden space 8192K, 100% used [0x33210000, 0x33a10000, 0x33a10000)
  from space 1024K,  71% used [0x33a10000, 0x33ac6038, 0x33b10000)
  to   space 1024K,   0% used [0x33b10000, 0x33b10000, 0x33c10000)
 tenured generation   total 10240K, used 5700K [0x33c10000, 0x34610000, 0x34610000)
   the space 10240K,  55% used [0x33c10000, 0x341a10b8, 0x341a1200, 0x34610000)
 compacting perm gen  total 12288K, used 168K [0x34610000, 0x35210000, 0x38610000)
   the space 12288K,   1% used [0x34610000, 0x3463a390, 0x3463a400, 0x35210000)
    ro space 10240K,  42% used [0x38610000, 0x38a4f150, 0x38a4f200, 0x39010000)
    rw space 12288K,  54% used [0x39010000, 0x3968fad8, 0x3968fc00, 0x39c10000)

从运行结果可以看出,经过JVM的3次Minor GC,再经过两次full GC后已经无法再GC了,空间已经无法再扩展了,最终导致了OutOfMemoryError

你可能感兴趣的:(jvm内存)