附件3:eclipse memory analyze使用教程
http://jingyan.baidu.com/article/ce09321b620a3d2bff858ff5.html
簡單使用:
分析三步曲:
通常我們都會采用下面的“三步曲”來分析內存泄露問題:
首先,對問題發生時刻的系統內存狀態獲取一個整體印象。
第二步,找到最有可能導致內存泄露的元兇,通常也就是消耗內存最多的對象
接下來,進一步去查看這個內存消耗大戶的具體情況,看看是否有什麽異常的行為。
下面將用一個基本的例子來展示如何采用“三步曲”來查看生產的分析報告。
1.查看報告之一:內存消耗的整體狀況
在報告上最醒目的就是一張簡潔明了的餅圖,從圖上我們可以清晰地看到一個可疑對象消耗了系統 99% 的內存。
在圖的下方還有對這個可疑對象的進一步描述。我們可以看到內存是由 java.util.Vector 的實例消耗的,com.ibm.oti.vm.BootstrapClassLoader 負責這個對象的加載。這段描述非常短,但我相信您已經可以從中找到很多線索了,比如是哪個類占用了絕大多數的內存,它屬於哪個組件等等。
接下來,我們應該進一步去分析問題,為什麽一個 Vector 會占據了系統 99% 的內存,誰阻止了垃圾回收機制對它的回收。
查看報告之二:分析問題的所在
首先我們簡單回顧下 JAVA 的內存回收機制,內存空間中垃圾回收的工作由垃圾回收器 (Garbage Collector,GC) 完成的,它的核心思想是:對虛擬機可用內存空間,即堆空間中的對象進行識別,如果對象正在被引用,那麽稱其為存活對象,反之,如果對象不再被引用,則為垃圾對象,可以回收其占據的空間,用於再分配。
在垃圾回收機制中有一組元素被稱為根元素集合,它們是一組被虛擬機直接引用的對象,比如,正在運行的線程對象,系統調用棧裏面的對象以及被 system class loader 所加載的那些對象。堆空間中的每個對象都是由一個根元素為起點被層層調用的。因此,一個對象還被某一個存活的根元素所引用,就會被認為是存活對象,不能被回收,進行內存釋放。因此,我們可以通過分析一個對象到根元素的引用路徑來分析為什麽該對象不能被順利回收。如果說一個對象已經不被任何程序邏輯所需要但是還存在被根元素引用的情況,我們可以說這裏存在內存泄露。
現在,讓我們開始真正的尋找內存泄露之旅,點擊“Details ”鏈接,可以看到如圖 8 所示對可疑對象 1 的詳細分析報告。
我們查看下從 GC 根元素到內存消耗聚集點的最短路徑:我們可以很清楚的看到整個引用鏈,內存聚集點是一個擁有大量對象的集合,如果你對代碼比較熟悉的話,相信這些信息應該能給你提供一些找到內存泄露的思路了。
接下來,我們再繼續看看,這個對象集合裏到底存放了什麽,為什麽會消耗掉如此多的內存。在這張圖上,我們可以清楚的看到,這個對象集合中保存了大量 Person 對象的引用,就是它導致的內存泄露。
https://wenku.baidu.com/view/bc5b6b8dcaaedd3382c4d3c8.html
詳細教程:
1. Heap Dump
例子:
Heap Dump是一個Java進程在某個時間點上的內存快照。Heap Dump是有著多種格式的。不過總體上Heap Dump在觸發快照的時候都保存了java對象和類的信息。通常在寫Heap Dump文件前會觸發一次FullGC,所以Heap Dump文件中保存的是FullGC後留下的對象信息。
Memory Analyzer可以用來處理HPROF二進制Heap Dump文件、IBM系統dump文件(經過處理後)、以及來自各個平臺上的 IBM portable Heap Dumps (PHD)文件。
一般在Heap Dump文件中可以獲取到(這仍然取決於Heap Dump文件的類型)如下信息:
對象信息:類、成員變量、直接量以及引用值;
類信息:類加載器、名稱、超類、靜態成員;
Garbage Collections Roots:JVM可達的對象;
線程棧以及本地變量:獲取快照時的線程棧信息,以及局部變量的詳細信息。
Heap Dump文件中並不包含內存分配信息,所以通常無法通過Heap Dump文件解決是誰以及在哪裏創建了哪些對象這樣的問題。
附件3:eclipse memory analyze使用教程