共计 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 不夠用時,會發生記憶體抖動,影響程式執行穩定性。
編輯項目執行時的配置
添加虛擬機執行參數
執行後得到錯誤 Exception in thread “main” java.lang.OutOfMemoryError: Java heap space 如附圖
分析問題
使用 Eclipse 提供 Memory Analysis Tool
先到官方網站下載 解壓縮後執行 MemoryAnalyzer.exe 並選擇開啟 Heap Dump 如附圖
選擇剛剛生成的 java_pidxxxx.hprof 檔案 如附圖
選擇預設 Leak Suspects Report 會自動評估問題點
查看報告,如附圖提示在執行緒中有個物件占滿整個記憶體,可以點 Detail 進行查詢
點選樹狀圖標,可以查看整個記憶體分配樹狀結構
從下圖中可以發現 A 物件不斷生成 (占比 96%),造成 java.lang.Object 占用大量記憶體,此時開始分析是程式碼沒寫好,還是業務本身有問題
Shallow Heap: 表示物件本身所占用的記憶體大小
Retained Heap: 表示 當前物件本身大小 加上 直接或間接引用物件大小 的總和
使用 Visual VM 查看
直接到 jdk 目錄中 bin 資料夾下開啟 jvisualvm.exe 或者配置好 jdk 路徑後 cmd 輸入 jvisualvm.exe 皆可,如附圖點 Load 載入
切換選擇 Heap Dumps 如附圖
載入成功後如附圖選擇 Class 可以查看當前物件使用情況,可以發現 A 類生成了大量實例占用大部分記憶體,找到對應程式碼進行修改即可