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