java Dump文件分析
前言
dump文件是java虛擬機內存在某一時間點的快照文件,一般是.hprof文件,下面自己模擬一下本地內存溢出,生成dump文件,然后通過mat工具分析的過程。
配置虛擬機參數
要想本地模擬oom異常,那么建議將堆內存設置的小一點,那樣容易觸發
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${目錄} -Xms20m -Xmx20m
- -XX:+HeapDumpOnOutOfMemoryError表示jvm發生oom異常時,自動生成dump文件,文件格式一般是:java_pid20804.hprof ,其中20804是java進程id
- -XX:HeapDumpPath=${目錄},表示生成dump文件的目錄,也可以指定文件名稱,例如:-XX:HeapDumpPath=${目錄}/java_heapdump.hprof,此步驟實驗出了點問題,暫時跳過
- -Xms:表示給jvm分配的初始化堆內存
- -Xmx:表示最大堆內存
模擬oom異常的程序
public class Test1 {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
while (true){
Person person = new Person();
person.setDate(new Date());
person.setAge(20);
person.setName("test");
personList.add(person);
}
}
}
很明顯,一直創建Person對象,卻又無法釋放,很快就內存溢出了。
java.lang.OutOfMemoryError: GC overhead limit exceeded
Dumping heap to java_pid21892.hprof ...
Heap dump file created [33907612 bytes in 0.152 secs]
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at Test1.main(Test1.java:15)
生成的文件名稱是java_pid21892.hprof,在項目的根目錄下面,文件大小33.9M
MAT工具分析dump文件
預覽
預覽界面,能清楚的看到整個堆總內存18.7M,但是有18.3M的內存被一個類的對象占用了

功能介紹

-
Histogram柱狀圖:以class類的維度展示每個class類的實例存在的個數、 占用的 [Shallow內存] 和 [Retained內存] 大小,可以分別排序顯示,從圖中看到,Person類的實例占用內存最大,而它就是沒有回收引起內存溢出的對象
-
Dominator Tree支配樹:該視圖以實例對象的維度展示當前堆內存中Retained Heap占用最大的對象,以及依賴這些對象存活的對象的樹狀結構
展開會展示下一層子節點,可以這么理解:父節點引用了子節點,子節點沒有被回收,所以父節點也沒法被回收
-
Thread Overview::可以看到線程棧/線程對象信息
把線程進行一個排序,同樣能看到引起內存溢出的是最上面線程里面的Person對象
-
可以選擇展示什么樣的報告信息,我們最開始打開dump文件時,會彈出一個窗口讓我們選擇,如果選錯了這里可以重新選擇
-
這里的功能比較強大,主要用來分析GC引用關系,每個對象到GCRoot的引用,可以在柱狀圖或者支配樹界面里選擇可疑對象進行分析,比較常用的兩個是:Path to GC ROOTS和Merge Shortest Paths to GC Roots,當然選中對象雙擊,也能進入到這樣的界面
-
Group分組功能:在 Histogram視圖 和 Domiantor Tree視圖時可操作,即以什么樣的維度展示
-
將分析報告以什么樣的格式導出,可選的有html、csv、txt。便於在團隊合作分析dump文件時,無需將龐大的dump文件拷貝過去,只需要生成以上格式的文件,就能很方便的轉移。
總結
以上用作筆記,方便下次本人查閱為主。