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


Java 堆 OutOfMemoryError

Java 堆是用來存儲對象實例的, 因此如果我們不斷地創建對象, 並且保證 GC Root 和創建的對象之間有可達路徑以免對象被垃圾回收, 那么當創建的對象過多時, 會導致 heap 內存不足, 進而引發 OutOfMemoryError 異常.

public class OutOfMemoryErrorTest{ public static void main (String[] args){ List<Integer> list = new ArryList<>(); int i=0; while(true){ list.add(i++); }}}

上面是一個引發 OutOfMemoryError 異常的代碼, 我們可以看到, 它就是通過不斷地創建對象, 並將對象保存在 list 中防止其被垃圾回收, 因此當對象過多時, 就會使堆內存溢出。

通過 java -Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError 我們設置了堆內存為 10 兆, 並且使用參數 -XX:+HeapDumpOnOutOfMemoryError 讓 JVM 在發生 OutOfMemoryError 異常時打印出當前的內存快照以便於后續分析.

編譯運行上述代碼后, 會有如下輸出:

>>>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 異常.

下面是具體的代碼:

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM