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