JVM 記憶體溢出

2,231次閱讀
尚無留言

共计 1265 个字符,预计需要花费 4 分钟才能阅读完成。

記錄下學習分析 JVM 記憶體溢出檢測的方法。

問題模擬

輸入下列程式碼

public class Main {public static void main(String[] args) {List<A> demoList = new ArrayList<>();
        while (true){demoList.add(new A());
        }
    }
}

class  A {}

配置下述虛擬機參數如附圖操作

-XX:+HeapDumpOnOutOfMemoryError -Xms20m -Xmx20m

參數說明

  • -XX:+HeapDumpOnOutOfMemoryError 當堆記憶體空間溢位時輸出堆的記憶體快照。
  • -Xms20m 初始的 heap 大小 20m
  • -Xmx20m 最大的 heap 大小 20m
  • -Xss 規定了每個執行緒堆棧的大小。一般情況下 256K 是足夠了。影響了此程序中併發執行緒數大小。

在很多情況下,-Xms 和 -Xmx 設定成一樣的。這麼設定,是因為當 Heap 不夠用時,會發生記憶體抖動,影響程式執行穩定性。

編輯項目執行時的配置

JVM 記憶體溢出

添加虛擬機執行參數

JVM 記憶體溢出

執行後得到錯誤 Exception in thread “main” java.lang.OutOfMemoryError: Java heap space 如附圖

JVM 記憶體溢出

分析問題

使用 Eclipse 提供 Memory Analysis Tool

先到官方網站下載 解壓縮後執行 MemoryAnalyzer.exe 並選擇開啟 Heap Dump 如附圖

JVM 記憶體溢出

選擇剛剛生成的 java_pidxxxx.hprof 檔案 如附圖

JVM 記憶體溢出

選擇預設 Leak Suspects Report 會自動評估問題點

JVM 記憶體溢出

查看報告,如附圖提示在執行緒中有個物件占滿整個記憶體,可以點 Detail 進行查詢 JVM 記憶體溢出

點選樹狀圖標,可以查看整個記憶體分配樹狀結構

JVM 記憶體溢出

從下圖中可以發現 A 物件不斷生成 (占比 96%),造成 java.lang.Object 占用大量記憶體,此時開始分析是程式碼沒寫好,還是業務本身有問題

JVM 記憶體溢出

Shallow Heap: 表示物件本身所占用的記憶體大小

Retained Heap: 表示 當前物件本身大小 加上 直接或間接引用物件大小 的總和

使用 Visual VM 查看

直接到 jdk 目錄中 bin 資料夾下開啟 jvisualvm.exe 或者配置好 jdk 路徑後 cmd 輸入 jvisualvm.exe 皆可,如附圖點 Load 載入

JVM 記憶體溢出

切換選擇 Heap Dumps 如附圖

JVM 記憶體溢出

載入成功後如附圖選擇 Class 可以查看當前物件使用情況,可以發現 A 類生成了大量實例占用大部分記憶體,找到對應程式碼進行修改即可

JVM 記憶體溢出

正文完
 0
評論(尚無留言)