Java 常見內存溢出異常與代碼實現

Java 堆 OutOfMemoryError

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)
Java 棧 StackOverflowError

咱們知道, 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
相關文章
相關標籤/搜索