Java 堆是用来存储对象实例的, 所以若是咱们不断地建立对象, 而且保证 GC Root 和建立的对象之间有可达路径以避免对象被垃圾回收, 那么当建立的对象过多时, 会致使 heap 内存不足, 进而引起 OutOfMemoryError 异常.java
public class OutOfMemoryErrorTest{ public static void main (String[] args){ List<Integer> list = new ArryList<>(); int i=0; while(true){ list.add(i++); }}}
上面是一个引起 OutOfMemoryError 异常的代码, 咱们能够看到, 它就是经过不断地建立对象, 并将对象保存在 list 中防止其被垃圾回收, 所以当对象过多时, 就会使堆内存溢出。spa
经过 java -Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError 咱们设置了堆内存为 10 兆, 而且使用参数 -XX:+HeapDumpOnOutOfMemoryError 让 JVM 在发生 OutOfMemoryError 异常时打印出当前的内存快照以便于后续分析.code
编译运行上述代码后, 会有以下输出:对象
>>>java -Xms10m - Xms10m-XX:HeapDumpOnOutOfMemoryError com.test.OutOfMemoryErrorTest 16-10-12 10:28 java.lang.OutOfMemoryError:Java heap space Dumping heap to java_pid1810.hprof... Heap dump file created [14212861 bytes in 0.128 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)
咱们知道, JVM 的运行时数据区中有一个叫作 虚拟机栈 的内存区域, 此区域的做用是: 每一个方法在执行时都会建立一个栈帧, 用于存储局部变量表, 操做数栈, 方法出口等信息.递归
所以咱们能够建立一个无限递归的递归调用, 当递归深度过大时, 就会耗尽栈空间, 进而致使了 StackOverflowError 异常.内存
下面是具体的代码:get
public class OutOfMemoryErrorTest{ public static void main (String [] srgs){ stackOutOfMemoryError(1); ) public static void stackOutOfMemoryError(int depth){ depth++; stackOutOfMemoryError(depth); }}
当编译运行上述的代码后, 会输出以下异常信息:虚拟机
Exception in thread "main" java.lang.StackOverflowError at com.test.OutOfMemoryErrorTest.stackOutOfMemoryError(OutOfMemoryErrorTest.java:27)
文章转载自 乐橙谷http://www.lechenggu.com/bbs/topic/57fda29f9c73a464f54e656e