Eclipse Memory Analyzer(MAT)使用java
平時開發、測試過程當中,有時會遇到OutOfMemoryError,Java堆溢出了,這代表程序有嚴重的問題,咱們須要找出形成OutOfMemoryError緣由。web
通常有兩種狀況:數組
一、內存泄露,對象已經死了,沒法經過垃圾收集器進行自動回收,經過找出泄露的代碼位置和緣由,纔好肯定解決方案;緩存
二、內存溢出,內存中的對象都還必須存活着,這說明Java堆分配空間不足,檢查堆設置大小(-Xmx與-Xms),檢查代碼是否存在對象生命週期太長、持有狀態時間過長的狀況。 多線程
以上是處理Java堆問題的思路,具體是怎麼進行分析,這裏介紹使用Eclipse Memory Analyzer tool(MAT)工具分析的過程。併發
java.lang.OutOfMemoryError:Java heap space工具
Java虛擬機堆裏面已經沒有更多的空間了。你正準備建立一個新的對象,可是這個要建立的對象須要的內存已經超過了虛擬機所剩的了。虛擬機會嘗試經過full GC來回收內存,若是不行的話,就會拋出這個信息(能夠經過-Xmx參數增長堆的大小來解決),若是不行,仍是要找到出現問題的緣由測試
java.lang.OutOfMemoryError:PermGen spacespa
和第一個現象差很少,不過這裏準備分配內存的空間是持久代。一樣的,空間已經不夠了,(增長了-XX:MaxPermSize這個參數的值,問題一般就解決了)
java.lang.OutOfMemoryError: GC overhead limit exceeded
這個問題有點特殊。這裏沒有提示說堆仍是持久代有問題,虛擬機只是說程序花在垃圾回收上的時間太多了,卻沒有什麼見效。默認的話,若是98%的時間都花在GC上而且回收了纔不到2%的空間的話,虛擬機纔會拋這個異常。
以上三種錯誤覆蓋了98%以上的場景
java.lang.OutOfMemoryError: unable to create new nativethread
若是虛擬機正在請求操做系統建立一個本地線程,而操做系統沒法建立的時候,你會收到這個報錯信息。
java.lang.OutOfMemoryError:nativeGetNewTLA
指當虛擬機不能分配新的線程本地空間(Thread Local Area)的時候錯誤信息。這個異常只有在jRockit虛擬機時纔會碰到。線程本地空間是多線程程序裏面爲了更有效的進行內存分配而創建的緩存。每個線程都有一份本身的緩存,當這個線程要建立對象的時候,就在這上面分配。若是你有不少線程同時併發,又要建立大量的對象,可能會出現這個問題,這種狀況下你能夠調整一下-XXtlaSize這個參數
java.lang.OutOfMemoryError:Requested array size exceeds VM limit
當建立一個超過虛擬機容許的大小的數組時,這條錯誤就會出現
java.lang.OutOfMemoryError:request bytes for . Out of swap space
這個錯誤是當虛擬機向本地操做系統申請內存失敗時拋出的。這個和用完了堆或者持久化中的內存的狀況有些不一樣。這個錯誤一般是在程序已經逼近平臺限制的時候產生的。這個信息告訴你可能已經用光了物理內存以及虛擬內存了。
2、MAT使用
一、Mat插件安裝
1)下載Mat ,Mat下載地址:http://www.eclipse.org/mat/
2)解壓下載包:放到eclipse或myeclipse安裝目錄的dropins目錄下
3)啓動eclipse或myeclipse,打開window - > open perspective,看到Memory Analysis證實安裝成功
也可使用其它方法進行安裝,不一一說明
二、生成dump文件
首前製造一條內存泄漏的用例,執行使程序報OutOfMemoryError
# ps -ef | grep java
# jmap -dump:live,format=b,file=mpfile1309
三、使用mat分析
啓動eclipse或myeclipse,打開file - > Open heap dump,在彈出的對話框選擇生成的dump文件(mpfile)打開heapDumps文件,就能夠看到MAT給出了overview page
結果查看:
1.Histogram能夠列出內存中的對象,對象的個數以及大小。
2. Dominator Tree能夠列出那個線程,以及線程下面的那些對象佔用的空間。
3.Top consumers經過圖形列出最大的object。
4.Leak Suspects經過MA自動分析泄漏的緣由。
分析:
Histogram以下圖:
Objects:類的對象的數量;
Shallow size:就是對象自己佔用內存的大小,不包含對其餘對象的引用,也就是對象頭加成員變量(不是成員變量的值)的總和;
Retained size:是該對象本身的shallow size,加上從該對象能直接或間接訪問到對象的shallow size之和。換句話說,retained size是該對象被GC以後所能回收到內存的總和。
咱們發現cn.test.TestBean類的對象佔用了不少空間。
DominatorTree以下圖:
咱們發現cn.test.TestMain-java.util.arraylist-java.lang.object用了不少空間
Top consumers以下圖:
這裏顯示了內存中最大的對象有哪些,他們對應的類是哪些,類加載器classloader是哪些。
有些時候,咱們在這裏就能夠看到代碼泄露的位置。
Leak Suspects以下圖:
該圖深色區域被懷疑有內存泄漏,深色區域就佔了69.1%。後面的描述,告訴咱們懷疑問題出在java.lang.object中。因此,MAT經過簡單的報告就說明了問題所在。
經過Leak Suspects的Problem Suspect 1點擊【Details】
從詳細內容中我明能夠明確的查出是cn.test.TestBean類的對象有問題,內存溢出
以上是經過MAT分析Tomcat應用程序,找到內存泄露的緣由,還有許多不足之處,但願你們多多指教
轉自:https://user.qzone.qq.com/731573705/blog/1436389384