摘要:如果說一個對象已經(jīng)不被任何程序邏輯所需要但是還存在被根元素引用的情況,我們可以說這里存在內(nèi)存泄露。圖內(nèi)存消耗聚集對象信息在這張圖上,我們可以清楚的看到,這個對象集合中保存了大量對象的引用,就是它導(dǎo)致的內(nèi)存泄露。
首先,之前在網(wǎng)上下載的是Myeclipse的插件 --memory analyzer,在網(wǎng)站的下面是Memory Analyzer的單機(jī)版,單機(jī)版安裝簡單,適合日常操作。下載地址:http://www.eclipse.org/mat/do...
之前一直糾結(jié)如何獲取一個Java項目的內(nèi)存分析的hprof文件,網(wǎng)上找了很多博客都是一筆帶過(這個很容易??。?,最后可能是搜索恰當(dāng),用JVM指令:
jmap -dump:format=b,file=文件名.hprof[pid]
導(dǎo)出內(nèi)存信息文件,然后利用Memory Analyzer工具打開進(jìn)行內(nèi)存分析(對于內(nèi)存泄露,OOM等分析有很大的幫助)。
分析三步曲通常我們都會采用下面的“三步曲”來分析內(nèi)存泄露問題:
首先,對問題發(fā)生時刻的系統(tǒng)內(nèi)存狀態(tài)獲取一個整體印象。
第二步,找到最有可能導(dǎo)致內(nèi)存泄露的元兇,通常也就是消耗內(nèi)存最多的對象
接下來,進(jìn)一步去查看這個內(nèi)存消耗大戶的具體情況,看看是否有什么異常的行為
。
下面將用一個基本的例子來展示如何采用“三步曲”來查看生產(chǎn)的分析報告。
查看報告之一:內(nèi)存消耗的整體狀況圖 7. 內(nèi)存泄露分析報告
如圖 7 所示,在報告上最醒目的就是一張簡潔明了的餅圖,從圖上我們可以清晰地看到一個可疑對象消耗了系統(tǒng) 99% 的內(nèi)存。在圖的下方還有對這個可疑對象的進(jìn)一步描述。我們可以看到內(nèi)存是由java.util.Vectorcom.ibm.oti.vm.BootstrapClassLoader 負(fù)責(zé)這個對象的加載。這段描述非常短,但我相信您已經(jīng)可以從中找到很多線索了,比如是哪個類占用了絕大多數(shù)的內(nèi)存,它屬于哪個組件等等。
接下來,我們應(yīng)該進(jìn)一步去分析問題,為什么一個 Vector 會占據(jù)了系統(tǒng) 99% 的內(nèi)存,誰阻止了垃圾回收機(jī)制對它的回收。
首先我們簡單回顧下 JAVA 的內(nèi)存回收機(jī)制,內(nèi)存空間中垃圾回收的工作由垃圾回收器 (Garbage Collector,GC) 完成的,它的核心思想是:對虛擬機(jī)可用內(nèi)存空間,即堆空間中的對象進(jìn)行識別,如果對象正在被引用,那么稱其為存活對象,反之,如果對象不再被引用,則為垃圾對象,可以回收其占據(jù)的空間,用于再分配。
在垃圾回收機(jī)制中有一組元素被稱為根元素集合,它們是一組被虛擬機(jī)直接引用的對象,比如,正在運行的線程對象,系統(tǒng)調(diào)用棧里面的對象以及被 system class loader 所加載的那些對象。堆空間中的每個對象都是由一個根元素為起點被層層調(diào)用的。因此,一個對象還被某一個存活的根元素所引用,就會被認(rèn)為是存活對象,不能被回收,進(jìn)行內(nèi)存釋放。因此,我們可以通過分析一個對象到根元素的引用路徑來分析為什么該對象不能被順利回收。如果說一個對象已經(jīng)不被任何程序邏輯所需要但是還存在被根元素引用的情況,我們可以說這里存在內(nèi)存泄露。
現(xiàn)在,讓我們開始真正的尋找內(nèi)存泄露之旅,點擊“Details ”鏈接,可以看到如圖 8 所示對可疑對象 1 的詳細(xì)分析報告。
圖 8. 可疑對象 1 的詳細(xì)分析報告
我們查看下從 GC 根元素到內(nèi)存消耗聚集點的最短路徑:
圖 9. 從根元素到內(nèi)存消耗聚集點的最短路徑
我們可以很清楚的看到整個引用鏈,內(nèi)存聚集點是一個擁有大量對象的集合,如果你對代碼比較熟悉的話,相信這些信息應(yīng)該能給你提供一些找到內(nèi)存泄露的思路了。
接下來,我們再繼續(xù)看看,這個對象集合里到底存放了什么,為什么會消耗掉如此多的內(nèi)存。
圖 10. 內(nèi)存消耗聚集對象信息
在這張圖上,我們可以清楚的看到,這個對象集合中保存了大量 Person 對象的引用,就是它導(dǎo)致的內(nèi)存泄露。
至此,我們已經(jīng)擁有了足夠的信息去尋找泄露點,回到代碼,我們發(fā)現(xiàn),是下面的代碼導(dǎo)致了內(nèi)存泄露 :
清單 1. 內(nèi)存泄漏的代碼段
while (1<2) { Person person = new Person("name","address",i); v.add(person); person = null; }總結(jié)
從上面的例子我們可以看到用 MAT 來進(jìn)行堆轉(zhuǎn)儲文件分析,尋找內(nèi)存泄露非常簡單,尤其是對于新手而言,這是一個很好的輔助分析工具。但是,MAT 絕對不僅僅是一個“傻瓜式”內(nèi)存分析工具,它還提供很多高級功能,比如 MAT 支持用 OQL(Object Query Language)對 heap dump 中的對象進(jìn)行查詢,支持對線程的分析等,有關(guān)這些功能的使用可以參考 MAT 的幫助文檔。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/71414.html
最近想要安裝MemoryAnalyzer(MAT)這個性能分析工具的插件,本以為網(wǎng)上教程那么多,教我一個技術(shù)一般的人足夠了,我安裝的是Myeclipse2017,可是在網(wǎng)上翻了一圈,大多數(shù)的Myeclipse教程都是10版本的,我呢,不想在論壇上問(沒耐心...),突然想到了自己當(dāng)初裝svn插件時的事情,類比一下是不是也可以呢?步驟如下:首先下載MemoryAnalyzer插件(這個一樣)http...
摘要:注本人剛接觸這東西時,走了很多彎路,并且不知道怎么解決。最后自己瞎搞,搞出來了,在這里給剛接觸的人寫個簡單提示,以免浪費時間,查找解決方案 本文章是寫給那些在eclipse上安裝了Memory analyzer工具但是確無法正常使用工具的人看的 如果你無法在eclipse上直接使用該工具,那么可以到http://www.eclipse.org/mat/do... 上面下載相對應(yīng)的 st...
摘要:不能滿足被回收的條件,盡管調(diào)用也還是不能得到回收這就造成了內(nèi)存泄漏。種解決單例中的內(nèi)存泄漏將引用置為銷毀監(jiān)聽使用弱引用將監(jiān)聽器放入弱引用中從弱引用中取出回調(diào)通過第七小點就能完美的解決單例中回調(diào)引起的內(nèi)存泄漏。我們?yōu)槭裁匆獌?yōu)化內(nèi)存 showImg(https://user-gold-cdn.xitu.io/2019/5/12/16aac64e31d8c501); 在 Android 中我們寫的...
摘要:在市面上找到一個好用的樹形穿梭框組件都很難,又不想僅僅因為一個穿梭框在之外引入其他重量級插件,因此就有了。版本增加穿梭框左側(cè)右側(cè)數(shù)據(jù)勾選事件,穿梭框左側(cè)右側(cè)底部。 el-tree-transfer 簡介·請先閱讀文檔及版本說明 因為公司業(yè)務(wù)使用vue框架,ui庫使用的element-ui。在市面上找到一個好用的vue樹形穿梭框組件都很難,又不想僅僅因為一個穿梭框在element-ui之...
閱讀 702·2023-04-26 01:53
閱讀 2837·2021-11-17 17:00
閱讀 2964·2021-09-04 16:40
閱讀 2059·2021-09-02 15:41
閱讀 906·2019-08-26 11:34
閱讀 1294·2019-08-26 10:16
閱讀 1402·2019-08-23 17:51
閱讀 907·2019-08-23 16:50