MAT內存溢出分析
元素介紹
List objects下面有兩個選項
with outgoing references:這個對象引用了那些對象。
with incoming references:這個對象被那些對象引用。
MAT設置
-
Shallow Heap、Retained Heap單位不顯示,無法直觀的查看,比較麻煩,我們可以設置單位顯示。
-
有時候dump文件很大,但是後發現實際的對象大小並不大,這時候可能是因爲有部分unreachable objects(不可達)對象沒有統計進來。注意:勾選後,需要重新打開dump文件。
Overview
提供有關堆轉儲文件整體情況的概覽信息,如堆大小、對象數量等。
Histogram
顯示了不同類別對象的數量和佔用內存大小,幫助你瞭解哪些對象佔用了大量內存。
Dominator Tree
顯示了佔用最多內存的對象及其引用關係,幫助你找到內存佔用較高的對象和潛在的內存泄漏問題。
Leak Suspects
根據對象引用關係和垃圾回收信息,提供了可能導致內存泄漏的對象列表。
分析步驟
- 打開文件後,直接點擊Leak Suspects會自動分析內存泄露的可疑對象。
- 分析完成會看到可疑信息,直接點擊Details,看看是那些對象。
- 這時候看到可疑的對象,我們可以看看這些可以對象引用哪裏對象(with outgoing references)來確定對象裏存儲的都是什麼。
- 可以看到我們這裏是非常多的HashMap,然後裏面存儲的對象如下圖,這時根據業務場景,去代碼裏面找相關代碼點。
- 在代碼裏面搜索後發現下面代碼,然後點擊new轉到定義,發現調用的竟然是有參的構造函數。
xxxMap.computeIfAbsent(xxxPo.getId(), ArrayList::new);
- 繼續看computeIfAbsent源碼,發現會將key傳遞進去。
- 那麼結果出來了,key數字較大,導致創建大量容量大的HashMap,對象且沒有引用,由於對象較大,因此直接進入老年代,回收也較困難,最終內存佔用大,GC回收喫力。
Visual VM排查
-
dump文件導入後,我們直接選擇Objects,查看有那些大對象。
-
然後點擊size排序後,展開想看對象,看看裏面都有什麼對象內容,一般都直接看內存佔用最大的裏面存放的對象即可。
-
也可以直接根據Instances進行聚合統計查看那個對象多,以及在items查看裏面有那些對象,再哪裏引用的。
idea自帶的dump分析工具
- 首先打開dump文件。
- 根據shallow排序,找到最大的對象,雙擊點進去。
- 查看前幾個對象,默認將最大排序在最上面的,就可以看到裏面存放的內容。
- 可以看到這個對象被那些對象引用。