本文內容如有錯誤、不足之處,歡迎技術愛好者們一同探討,在本文下面討論區留言,感謝。
簡介
OutOfMemoryError 簡稱 OOM
OutOfMemoryError 異常是 JVM 所拋出的,當JVM沒有足夠的可用內存來分配時,就會拋出。OutOfMemoryError 在 Exception 類層次結構中屬於 Error 類別。
繼承關係
從繼承關係中可以發現,OutOfMemoryError 繼承 VirtualMachineError 虛擬機異常
分類
- Java heap space:Java 堆空間錯誤,應用程序嘗試添加更多的數據放入堆空間區域,但沒有足夠的空間供它,可能會有大量的物理內存可用,但是 JVM 有堆大小限制。
- GC overhead limit exceeded:應用程序已經耗盡了幾乎所有的可用內存並且GC一直未能回收它或只能回收2%的可用空間。
- Permgen space:表示永久代的內存區域被耗盡,永久生成主要由裝入並存儲到 PermGen 中的類聲明組成,造成該錯誤的主要原因是永久區中裝入了太多的類或太大的類。
- Metaspace:元空間中消息指示所述元空間區域在存儲器中被耗盡。
- Unable to create new native thread:Java 應用程序已達到其可以啓動線程數的限制。
- Out of swap space:交換空間也已用盡,並且由於缺少物理內存和交換空間,新的嘗試分配失敗。
- Requested array size exceeds VM limit:請求的數組大小超出VM限制時,這意味着因錯誤而崩潰的應用程序正試圖分配一個大於 Java 虛擬機可以支持的數組。
例子
public class OutOfMemoryErrorDemo {
public static void main(String[] args) throws Exception {
int dummyArraySize = 15;
System.out.println("Max JVM memory: " + Runtime.getRuntime().maxMemory());
long memoryConsumed = 0;
try {
long[] memoryAllocated = null;
for(int loop = 0; loop < Integer.MAX_VALUE; loop++) {
memoryAllocated = new long[dummyArraySize];
memoryAllocated[0] = 0;
memoryConsumed += dummyArraySize * Long.SIZE;
System.out.println("Memory Consumed till now: " + memoryConsumed);
dummyArraySize *= dummyArraySize * 2;
Thread.sleep(500);
}
} catch (OutOfMemoryError outofMemory) {
System.out.println("Catching out of memory error");
//Log the information, so that we can generate the statistics
throw outofMemory;
}
}
}
輸出:
Max JVM memory: 119537664
Memory Consumed till now: 960
Memory Consumed till now: 29760
Memory Consumed till now: 25949760
Catching out of memory error
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at OutOfMemoryErrorDemo.main(OutOfMemoryErrorDemo.java:9)
結論
已經簡單的瞭解了一下關於OOM是什麼,以及它有哪些情況會產生和分類。
參考資料
介紹JVM中OOM的8種類型
What is an OutOfMemoryError and steps to find the root cause of OOM in Java?(什麼是OutOfMemoryError以及查找Java中OOM根本原因的步驟?)