eclipse占用内存过大_Java性能调优学习(三)-jmap+mat分析内存溢出问题实战
上一節我們講了jinfo,jstat,jmap的使用,還簡單的講了下如何使用jmap導出內存映像文件,這次,我們來實戰一把內存溢出問題。
環境準備
首先我們先模擬一下內存溢出的場景,以下這段代碼在訪問后肯定會造成堆內存溢出,代碼如下:
@RestController@RequestMapping("/section1")public class TestHeapController { private List heapList = new ArrayList<>(); /*** * -Xms16m -Xmx32m */ @GetMapping("/heap") public ResultVO testHeap() { int i = 0; while (true) { Student student = new Student(i++, UUID.randomUUID().toString()); System.out.println(student.toString()); heapList.add(student); } }}那么我們如何解決這樣的問題,在生產環境中,代碼肯定不會這么清晰簡單,那么我們怎么去分析和解決呢?我們需要導出內存映像文件來分析解決。
有兩種方式可以導出內存映像文件,這邊我們在重溫一下。
有兩種方式可以導出映像文件:
1. 配置參數內存溢出自動導出
-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=./2. 使用jmap命令手動導出
關于jmap如何導出,可以看我的上一篇文章,Java性能調優學習(二)-jinfo,jstat,jmap的使用
下面我們先準備一下需要分析的內存映像文件,配置JVM參數后,啟動我們剛剛的實例代碼,開多個瀏覽器多次訪問后,很快就會出現異常,這個時候由于配置了參數,會自動導出內存映像文件,我們將這個文件先放好,備用。
參數配置
自動導出
下面就輪到我們的內存分析工具MAT登場啦。
MAT
MAT(MemoryAnalyzerTool)工具是eclipse的一個插件(MAT也可以單獨使用),使用起來非常方便,尤其是在分析大內存的dump文件時,可以非常直觀的看到各個對象在堆空間中所占用的內存大小、類實例數量、對象引用關系、利用OQL對象查詢,以及可以很方便的找出對象GCRoots的相關信息,當然最吸引人的還是能夠快速為開發人員生成內存泄露報表,方便定位問題和分析問題。
MAT工具的下載地址為:https://www.eclipse.org/mat/downloads.php
下載完成后,直接解壓,運行其中的MemoryAnalyzer.exe文件即可啟動MAT工具,如下所示:
mat目錄
點擊File->Open heap dump 打開之前導出的dump文件,將會生成Overview選項,效果如圖:
在Overview選項中,以餅狀圖的形式列舉出了程序內存消耗的一些基本信息,其中每一種不同顏色的餅塊都代表了不同比例的內存消耗情況。
點擊overview右側的panel,我們可以看到如下圖所示的效果,里面列舉了可能的泄漏點,并且對泄漏點進行了描述。
疑似的泄漏點
再介紹一下我們工具欄上常用的一些功能:Dominator Tree,HistogramDominator Tree:
如果需要定位內存泄露的代碼點,我們可以通過Dominator Tree菜單選項來進行排查。
Dominator Tree提供了一個列表。可以看到對象之間dominator關系樹。從MAT的Dominator tree中可以看到占用內存最大的對象以及每個對象的Dominator。
Dominator Tree
點開“+”符號,可以進一步查看內層應用情況,同時還可以看到對應類對象的屬性值,如下所示:
展開圖
可以看到,我們這邊有一大堆的Studen一直占用著內存,沒有被回收,那么肯定是有問題的。
因為咱們的實驗代碼比較簡單,但是在生產環境上肯定是沒有這么清晰的,所以通常在排查內存泄漏的時候,我們還需要排除掉虛引用/弱引用/軟引用等引用鏈,查看強引用。(強引用是使用最普遍的引用。如果一個對象具有強引用,那垃圾回收器絕不會回收它。)
那么如何排除掉虛引用/弱引用/軟引用等引用鏈呢?如下圖所示,選擇exclude all phantom/weak/soft etc.references,意思是查看排除虛引用/弱引用/軟引用等的引用鏈,因為被虛引用/弱引用/軟引用的對象可以直接被GC給回收,我們要看的就是某個對象否還存在Strong 引用鏈(在導出HeapDump之前要手動出發GC來保證),如果有,則說明存在內存泄漏,然后再去排查具體引用。
排除其他引用
Dominator Tree講完了,下面我們來講一下工具欄上還有一個好用的功能Histogram。
Histogram
Histogram清晰的列出了每個類的Objects,Shallow Heap,Retained Heap,關于Shallow Heap和Retained Heap的具體意義,在有空的時候我會單獨講解,現在可以先理解為對象本身占用的內存大小和該對象被回收時可以釋放的內存大小。
Histogram通過正則過濾
當我們找到疑似存在泄漏的類之后,我們可以進行進一步分析,排除引用。
排除引用
還有一些會在平時用到的右鍵菜單中的按鈕:
List objects :
with incoming references 引用到該對象的對象
with outcoming references 被該對象引用的對象
Show objects by class :
incoming references 引用到該對象的對象
outcoming references 被該對象引用的對象
總結
今天為大家帶來了jmap+mat內存分析,感興趣的小伙伴們可以收藏并關注我,為大家持續帶來干貨。
總結
以上是生活随笔為你收集整理的eclipse占用内存过大_Java性能调优学习(三)-jmap+mat分析内存溢出问题实战的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 带听的网名102个
- 下一篇: 6 日期字符串转日期_Java日期时间A