Eclipse Memory Analyzee Java內存分析工具安裝教程和使用

這裏,內存映像工具利用的是Eclipse Memory Analyzee,對Dump出來的堆轉存儲快照進行分析,能夠分清楚究竟是出現了內存泄露(Memory Leak)仍是內存溢出(Memory Overflow)。java

在Eclipse中離線安裝MemoryAnalyzee的步驟以下(因爲在線安裝可能會有網絡問題):網絡

(1)去官網下載離線安裝包:app

即下載MemoyAnalyzer-1.6.1.201611251412.zip包。eclipse

(2)下載以後解壓獲得以下文件內容:jvm

(3)打開Eclipse->Help->Install new Software,以下:ide


將乾菜下載好的路徑引入其中。點擊Ok。工具

(4)點擊Avaliable Software Sites字體

注意:將裏面,全部有關http鏈接的去掉勾選,不然,在更新的時候可能失敗,以下:ui

只要location是http開頭的就去勾選。spa

(5)去掉Contact all update sites during install to findrequired software前面的勾


(6)點擊next,便可成功安裝

那麼:Eclipse Memory Analyzer如何使用呢?

爲了使用MAT,即Memory Analyzer Tool,這裏咱們使用的是Eclipse Memory Anaylyzer須要先明白內存分析的數據源是如何產生的。有兩種方式:

(1)經過jmap(Memory Map for Java)命令生成堆轉儲快照(通常稱爲heapdump或dump文件)

(2)經過JVM參數 -XX:+HeapDumpOnOutOfMemoryError可讓JVM在出現內存溢出異常時Dump出當前內存堆轉存儲快照以便過後進行分析。

這裏先介紹第二種狀況,即JVM中內存溢出後可以自動dump出對轉存儲快照。

編寫一個簡單的堆溢出的代碼以下:
class User{
    String name;
    String sex;
    @Override
    public String toString() {
        return "User [name=" + name + ", sex=" + sex + "]";
    }
}

public class MemoryLeak1 {
    public static void main(String[] args) {
        List<User> list = new ArrayList<User>();
        while(true){
            list.add(new User());
        }

    }
}
分析:上面的代碼中,經過List list中不斷的添加new User()實例,由於list的做用域是和main方法同樣的,而new出來的額User的實例被list中的元素引用,因此,經過while循環new 出來的User不會被GC。所以,致使內存溢出。

爲了分析JVM中內存溢出的狀況,須要添加JVM的參數:-XX:+HeapDumpOnOutOfMemoryError,操做步驟以下:

點擊:Run->DebugConfiguration,在左側列表下的Java Application下對應的你的Java類,好比:我這裏的類是MemoryLeak1,以下:

在Arguments中的VM arguments下填寫:-XX:+HeapDumpOnOutOfMemoryError,而後,點擊Apply,以及點擊Debug,即運行咱們以前寫的那段會內存溢出的代碼。在運行大概兩三分鐘以後,出現以下異常信息:

能夠看到異常信息爲java.lang.OutOfMemoryError:Java heap space,即內存溢出異常。上面的黑色字體是將內存堆轉儲爲dump文件,這裏的dump文件名稱爲:java_pid7568.hprof,其中7568是當前Java程序的進程號。

另外,須要注意的是剛纔咱們生成的dump文件java_pid7568.hprof,這裏的路徑默認是在項目的根路徑下,若是你沒有看到該文件,須要強制刷新當前項目,好比:點擊項目,而後按F5。


接下來,就是將該dump文件經過咱們上面的Memory Analyzer進行分析,步驟以下:

(1)在工具欄上:File->Open File…,選中java_pid7568.hprof文件,並打開


(2)可是產生了以下錯誤:


點擊OK以後,有:


看了上述的問題,大體的意思是說內存溢出錯誤,後面又說了「Runngin Eclipse」,大體猜想應該是系統給Eclipse軟件分配的內存過小,另外,咱們查看了java_pid7568.hprof文件的大小爲3,355,137KB,大概是3g左右。因而,咱們又查看了Eclipse軟件下的eclipse.ini文件:


那麼eclipse.ini中的參數各是什麼意思呢?在理解這些參數以前,須要知道Eclipse這款軟件是由java語言開發的,所以,其自身也須要jvm支持的,那麼它的默認參數配置就在eclipse.ini中,以下:

-startup
plugins/org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.300.v20150602-1417
-product
org.eclipse.epp.package.jee.product
--launcher.defaultAction
openFile
--launcher.XXMaxPermSize
512M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
512m
--launcher.defaultAction
openFile
--launcher.appendVmargs
-vmargs
-Dosgi.requiredJavaVersion=1.7
-Xms512m
-Xmx1024m
如上,咱們能夠看到,Eclipse須要java 1.7版本的支持,通常咱們須要安裝Jdk環境,假如咱們刪除掉Jdk環境,那麼會出現以下錯誤:


所以,Eclipse其實本質上就是一個Java程序,咱們能夠經過JVM自帶的jps命令來查看java進程,以下:


咱們輸入jps發現進程id號爲4316,與咱們在Windows任務管理器中看到的eclipse對應的PID是一致的,證實了咱們說的Eclipse本質上也是一個Java程序。

也須要設置最下的堆大小,這裏默認是-Xms512m,最大的堆大小-Xmx1024m,顯然最大的堆大小爲1024m大概是1G左右,明顯小於咱們要打開的文件3G的大小,這裏,咱們將-Xmx設置5120m,以下:

-Dosgi.requiredJavaVersion=1.7
-Xms512m
-Xmx5120m
再次重啓Eclipse,並打開咱們以前的那個大概3G左右的dump文件,則能夠成功打開。


這裏,主要看下「Histogram」,這個會列出每一個類的實例個數。以及「Leak Suspects」分析內存可能產生泄露的緣由。咱們看下:

Histogram:


這裏Class Name是對應類型,Objects是對應實例的個數,很明顯類com.tim.User的實例個數居然達到70,091,071個,那麼後面跟着的兩列:Shallow Heap和Retained Heap是什麼東西?

問題:Shallow Heap和Retained Heap 的區別?

ShallowHeap:Shallow中文的意思是膚淺、淺的意思,則Shallow Heap咱們能夠理解爲淺的表面的堆,是對象自己佔據的內存的大小,不包含其所引用的對象。

RetainedHeap:Retained中文的意思是保留、保存的意思,則Retained Heap咱們能夠理解爲保留、保存的堆,是當前對象大小+當前對象可直接或者間接引用到的對象的大小總和。

分析:上面的Shallow Heap是比較好理解的,而要真正理解Retained Heap須要先理解GC roots是如何工做的?

GCroots:

---------------------   

相關文章
相關標籤/搜索