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