eclipse占用内存过大_Java性能调优学习(三)-jmap+mat分析内存溢出问题实战
上一節(jié)我們講了jinfo,jstat,jmap的使用,還簡(jiǎn)單的講了下如何使用jmap導(dǎo)出內(nèi)存映像文件,這次,我們來(lái)實(shí)戰(zhàn)一把內(nèi)存溢出問題。
環(huán)境準(zhǔn)備
首先我們先模擬一下內(nèi)存溢出的場(chǎng)景,以下這段代碼在訪問后肯定會(huì)造成堆內(nèi)存溢出,代碼如下:
@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); } }}那么我們?nèi)绾谓鉀Q這樣的問題,在生產(chǎn)環(huán)境中,代碼肯定不會(huì)這么清晰簡(jiǎn)單,那么我們?cè)趺慈シ治龊徒鉀Q呢?我們需要導(dǎo)出內(nèi)存映像文件來(lái)分析解決。
有兩種方式可以導(dǎo)出內(nèi)存映像文件,這邊我們?cè)谥販匾幌隆?/p>
有兩種方式可以導(dǎo)出映像文件:
1. 配置參數(shù)內(nèi)存溢出自動(dòng)導(dǎo)出
-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=./2. 使用jmap命令手動(dòng)導(dǎo)出
關(guān)于jmap如何導(dǎo)出,可以看我的上一篇文章,Java性能調(diào)優(yōu)學(xué)習(xí)(二)-jinfo,jstat,jmap的使用
下面我們先準(zhǔn)備一下需要分析的內(nèi)存映像文件,配置JVM參數(shù)后,啟動(dòng)我們剛剛的實(shí)例代碼,開多個(gè)瀏覽器多次訪問后,很快就會(huì)出現(xiàn)異常,這個(gè)時(shí)候由于配置了參數(shù),會(huì)自動(dòng)導(dǎo)出內(nèi)存映像文件,我們將這個(gè)文件先放好,備用。
參數(shù)配置
自動(dòng)導(dǎo)出
下面就輪到我們的內(nèi)存分析工具M(jìn)AT登場(chǎng)啦。
MAT
MAT(MemoryAnalyzerTool)工具是eclipse的一個(gè)插件(MAT也可以單獨(dú)使用),使用起來(lái)非常方便,尤其是在分析大內(nèi)存的dump文件時(shí),可以非常直觀的看到各個(gè)對(duì)象在堆空間中所占用的內(nèi)存大小、類實(shí)例數(shù)量、對(duì)象引用關(guān)系、利用OQL對(duì)象查詢,以及可以很方便的找出對(duì)象GCRoots的相關(guān)信息,當(dāng)然最吸引人的還是能夠快速為開發(fā)人員生成內(nèi)存泄露報(bào)表,方便定位問題和分析問題。
MAT工具的下載地址為:https://www.eclipse.org/mat/downloads.php
下載完成后,直接解壓,運(yùn)行其中的MemoryAnalyzer.exe文件即可啟動(dòng)MAT工具,如下所示:
mat目錄
點(diǎn)擊File->Open heap dump 打開之前導(dǎo)出的dump文件,將會(huì)生成Overview選項(xiàng),效果如圖:
在Overview選項(xiàng)中,以餅狀圖的形式列舉出了程序內(nèi)存消耗的一些基本信息,其中每一種不同顏色的餅塊都代表了不同比例的內(nèi)存消耗情況。
點(diǎn)擊overview右側(cè)的panel,我們可以看到如下圖所示的效果,里面列舉了可能的泄漏點(diǎn),并且對(duì)泄漏點(diǎn)進(jìn)行了描述。
疑似的泄漏點(diǎn)
再介紹一下我們工具欄上常用的一些功能:Dominator Tree,HistogramDominator Tree:
如果需要定位內(nèi)存泄露的代碼點(diǎn),我們可以通過Dominator Tree菜單選項(xiàng)來(lái)進(jìn)行排查。
Dominator Tree提供了一個(gè)列表。可以看到對(duì)象之間dominator關(guān)系樹。從MAT的Dominator tree中可以看到占用內(nèi)存最大的對(duì)象以及每個(gè)對(duì)象的Dominator。
Dominator Tree
點(diǎn)開“+”符號(hào),可以進(jìn)一步查看內(nèi)層應(yīng)用情況,同時(shí)還可以看到對(duì)應(yīng)類對(duì)象的屬性值,如下所示:
展開圖
可以看到,我們這邊有一大堆的Studen一直占用著內(nèi)存,沒有被回收,那么肯定是有問題的。
因?yàn)樵蹅兊膶?shí)驗(yàn)代碼比較簡(jiǎn)單,但是在生產(chǎn)環(huán)境上肯定是沒有這么清晰的,所以通常在排查內(nèi)存泄漏的時(shí)候,我們還需要排除掉虛引用/弱引用/軟引用等引用鏈,查看強(qiáng)引用。(強(qiáng)引用是使用最普遍的引用。如果一個(gè)對(duì)象具有強(qiáng)引用,那垃圾回收器絕不會(huì)回收它。)
那么如何排除掉虛引用/弱引用/軟引用等引用鏈呢?如下圖所示,選擇exclude all phantom/weak/soft etc.references,意思是查看排除虛引用/弱引用/軟引用等的引用鏈,因?yàn)楸惶撘?弱引用/軟引用的對(duì)象可以直接被GC給回收,我們要看的就是某個(gè)對(duì)象否還存在Strong 引用鏈(在導(dǎo)出HeapDump之前要手動(dòng)出發(fā)GC來(lái)保證),如果有,則說(shuō)明存在內(nèi)存泄漏,然后再去排查具體引用。
排除其他引用
Dominator Tree講完了,下面我們來(lái)講一下工具欄上還有一個(gè)好用的功能Histogram。
Histogram
Histogram清晰的列出了每個(gè)類的Objects,Shallow Heap,Retained Heap,關(guān)于Shallow Heap和Retained Heap的具體意義,在有空的時(shí)候我會(huì)單獨(dú)講解,現(xiàn)在可以先理解為對(duì)象本身占用的內(nèi)存大小和該對(duì)象被回收時(shí)可以釋放的內(nèi)存大小。
Histogram通過正則過濾
當(dāng)我們找到疑似存在泄漏的類之后,我們可以進(jìn)行進(jìn)一步分析,排除引用。
排除引用
還有一些會(huì)在平時(shí)用到的右鍵菜單中的按鈕:
List objects :
with incoming references 引用到該對(duì)象的對(duì)象
with outcoming references 被該對(duì)象引用的對(duì)象
Show objects by class :
incoming references 引用到該對(duì)象的對(duì)象
outcoming references 被該對(duì)象引用的對(duì)象
總結(jié)
今天為大家?guī)?lái)了jmap+mat內(nèi)存分析,感興趣的小伙伴們可以收藏并關(guān)注我,為大家持續(xù)帶來(lái)干貨。
總結(jié)
以上是生活随笔為你收集整理的eclipse占用内存过大_Java性能调优学习(三)-jmap+mat分析内存溢出问题实战的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 带听的网名102个
- 下一篇: elaseticsearch 配置ik分