歡迎光臨
每天分享高質量文章

一文瞭解 OutOfMemory 及解決方案

(給ImportNew加星標,提高Java技能)

 

來自:唐尤華

譯自:https://bloggceasy.files.wordpress.com/2015/05/outofmemoryerror2.pdf

 

1. Java 堆空間

 

發生頻率

5顆星

 

造成原因

  1. 無法在 Java 堆中分配物件
  2. 吞吐量增加
  3. 應用程式無意中儲存了物件取用,物件無法被 GC 回收
  4. 應用程式過度使用 finalizer。finalizer 物件不能被 GC 立刻回收。finalizer 由結束佇列服務的守護執行緒呼叫,有時 finalizer 執行緒的處理能力無法跟上結束佇列的增長

 

解決方案

單位對應:GB -> G, g;MB -> M, m;KB -> K, k

  1. 使用 -Xmx 增加堆大小
  2. 修複應用程式中的記憶體洩漏

 

2. GC 開銷超過限制

 

發生頻率

5顆星

 

造成原因

  1. Java 行程98%的時間在進行垃圾回收,恢復了不到2%的堆空間,最後連續5個(編譯時常量)垃圾回收一直如此。

 

解決方案

 

  1. 使用 -Xmx 增加堆大小
  2. 使用 -XX:-UseGCOverheadLimit 取消 GC 開銷限制
  3. 修複應用程式中的記憶體洩漏

 

3. 請求的陣列大小超過虛擬機器限制

 

發生頻率

2顆星

 

造成原因

  1. 應用程式試圖分配一個超過堆大小的陣列

 

解決方案

  1. 使用 -Xmx 增加堆大小
  2. 修複應用程式中分配巨大陣列的 bug

 

4. Permgen 空間

 

發生頻率

3顆星

 

造成原因

Permgen 空間包含:

  • 類的名字、欄位、方法
  • 與類相關的物件陣列和型別陣列
  • JIT 編譯器最佳化

 

當 Permgen 空間用盡時,將丟擲異常。

 

解決方案

  1. 使用 -XX: MaxPermSize 增加 Permgen 大小
  2. 不重啟應用部署應用程式可能會導致此問題。重啟 JVM 解決

 

5. Metaspace

 

發生頻率

3顆星

 

造成原因

  1. 從 Java 8 開始 Permgen 改成了 Metaspace,在本機記憶體中分配 class 元資料(稱為 metaspace)。如果 metaspace 耗盡,則丟擲異常

 

解決方案

  1. 透過命令列設定 -XX: MaxMetaSpaceSize 增加 metaspace 大小
  2. 取消 -XX: maxmetsspacedize
  3. 減小 Java 堆大小,為 MetaSpace 提供更多的可用空間
  4. 為伺服器分配更多的記憶體
  5. 可能是應用程式 bug,修複 bug

 

6. 無法新建本機執行緒

 

發生頻率

5顆星

 

造成原因

  1. 記憶體不足,無法建立新執行緒。由於執行緒在本機記憶體中建立,報告這個錯誤表明本機記憶體空間不足

 

解決方案

  1. 為機器分配更多的記憶體
  2. 減少 Java 堆空間
  3. 修複應用程式中的執行緒洩漏。
  4. 增加作業系統級別的限制
  • ulimit -a
  • 使用者行程數增大 (-u) 1800
  • 使用 -Xss 減小執行緒堆疊大小

 

7. 殺死行程或子行程

 

發生頻率

1顆星

 

造成原因

  1. 核心任務:記憶體不足結束器,在可用記憶體極低的情況下會殺死行程

 

解決方案

  1. 將行程遷移到不同的機器上
  2. 給機器增加更多記憶體

 

與其他 OOM 錯誤不同,這是由作業系統而非 JVM 觸發的。

 

8. 發生 stack_trace_with_native_method

 

發生頻率

1顆星

 

造成原因

  1. 本機方法(native method)分配失敗
  2. 列印的堆疊跟蹤資訊,最頂層的幀是本機方法

 

解決方案

  1. 使用作業系統本地工具進行診斷

看完本文有收穫?請轉發分享給更多人

關註「ImportNew」,提升Java技能

喜歡就點「好看」唄~

 

    贊(0)

    分享創造快樂