JVM 記憶體溢出
記錄下學習分析 JVM 記憶體溢出檢測的方法。
問題模擬
輸入下列程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class Main { public static void main(String[] args) { List<A> demoList = new ArrayList<>(); while (true){ demoList.add(new A()); } } } class A { } |
配置下述虛擬機參數如附圖操作
1 |
-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類生成了大量實例占用大部分記憶體,找到對應程式碼進行修改即可
相逢就是有緣,留下足跡吧!