【Android】Eclipse Memory Analyzer 進行堆內存溢出分析

    MAT 不是一個萬能工具,它並不能處理全部類型的堆存儲文件。java

     不一樣廠家的 JVM 所生成的堆轉儲文件在數據存儲格式以及數據存儲內容上有不少區別, 可是比較主流的廠家和格式,例如 Sun, HP, SAP 所採用的 HPROF 二進制堆存儲文件,以及 IBM 的 PHD 堆存儲文件等都能被很好的解析。
    另外, 有不少的工具,例如 JMap,JConsole 均可以幫助咱們獲得一個堆轉儲文件。

1.一鍵式的堆存儲分析功能

     生成分析報告

首先,啓動安裝配置好的 Memory Analyzer tool , 而後選擇菜單項 File- Open Heap Dump(eclipse會自動載入)來加載須要分析的堆轉儲文件。android

文件加載完成後,你能夠看到以下圖所示的界面瀏覽器

經過上面的概覽,咱們對內存佔用狀況有了一個整體的瞭解。多線程

另外,MAT 工具提供了一個很貼心的功能,將報告的內容壓縮打包到一個 zip 文件,並把它存放到原始堆轉儲文件的存放目錄下,這樣若是您須要和同事一塊兒分析這個內存問題的話,只須要把這個小小的 zip 包發給他就能夠了,不須要把整個堆文件發給他。而且整個報告是一個 HTML 格式的文件,用瀏覽器就能夠輕鬆打開。eclipse

接下來咱們就能夠來看看生成的報告都包括什麼內容,能不能幫咱們找到問題所在吧。您能夠點擊工具欄上的 Leak Suspects 菜單項來生成內存泄露分析報告,也能夠直接點擊餅圖下方的 Reports->Leak Suspects 連接來生成報告。工具

2.分析三步曲

一般咱們都會採用下面的「三步曲」來分析內存泄露問題:優化

  1. 首先,對問題發生時刻的系統內存狀態獲取一個總體印象。
  2. 第二步,找到最有可能致使內存泄露的元兇,一般也就是消耗內存最多的對象
  3. 接下來,進一步去查看這個內存消耗大戶的具體狀況,看看是否有什麼異常的行爲。

下面將用一個基本的例子來展現如何採用「三步曲」來查看生產的分析報告。spa

2.1 查看報告之一:內存消耗的總體情況

  內存泄露分析報告,以下圖所示
  
 
 
  如上圖所示,在報告上最醒目的就是一張簡潔明瞭的餅圖,從圖上咱們能夠清晰地看到一個可疑對象消耗了系統 70% 的內存。
  
  在圖的下方還有對這個可疑對象的進一步描述。咱們能夠看到內存是由 android.content.res.Resources 的實例消耗的,system class loader 負責這個對象的加載。這段描述很是短,但已經能夠從中找到不少線索了,好比是哪一個類佔用了絕大多數的內存,它屬於哪一個組件等等。
  接下來,咱們應該進一步去分析問題,爲何一個Resources會佔據了系統 70% 的內存,誰阻止了垃圾回收機制對它的回收。

2.2 查看報告之一:分析問題的所在

  首先簡單回顧下 JAVA 的內存回收機制,內存空間中垃圾回收的工做由垃圾回收器 (Garbage Collector,GC) 完成的,它的核心思想是:對虛擬機可用內存空間,即堆空間中的對象進行識別,若是對象正在被引用,那麼稱其爲存活對象,反之,若是對象再也不被引用,則爲垃圾對象,能夠回收其佔據的空間,用於再分配。
在垃圾回收機制中有一組元素被稱爲根元素集合,它們是一組被虛擬機直接引用的對象,好比,正在運行的線程對象,系統調用棧裏面的對象以及被 system class loader 所加載的那些對象。堆空間中的每一個對象都是由一個根元素爲起點被層層調用的。
  所以,一個對象還被某一個存活的根元素所引用,就會被認爲是存活對象,不能被回收,進行內存釋放。所以,咱們能夠經過分析一個對象到根元素的引用路徑來分析爲何該對象不能被順利回收。若是說一個對象已經不被任何程序邏輯所須要可是還存在被根元素引用的狀況,咱們能夠說這裏存在內存泄露。

如今,讓咱們開始真正的尋找內存泄露之旅,點擊「Details 」連接,能夠看到以下圖所示對可疑對象的詳細分析報告。線程

  
  咱們查看下從 GC 根元素到內存消耗匯集點的最短路徑:
  

咱們能夠很清楚的看到整個引用鏈,內存匯集點是一個擁有大量對象的集合,若是你對代碼比較熟悉的話,相信這些信息應該能給你提供一些找到內存泄露的思路了。對象

接下來,咱們再繼續看看,這個對象集合裏到底存放了什麼,爲何會消耗掉如此多的內存。

在這張圖上,咱們能夠清楚的看到,這個對象集合中保存了大量圖片對象的引用,可能就是它致使的內存泄露等問題。

再仔細看......

 

實際上這些位圖真正佔用的內存只有一丁點,可是java虛擬機爲其保留了70%的內存備用,這些內存沒有被回收,因此利用率幾乎爲 0 !

今後處你們均可以知道了,應用裏面圖片多了實際上是一件悲劇的事,至少可能會給應用帶來許多不可預知的問題,並且在圖片方面的內存優化是比較麻煩的,哎,最近搞內存泄露,涉及到動態庫,JNI,多線程,資源同步與競爭等,蛋疼的事 ......

 

有些圖片爲Android預加載部分的,具體可參看下面網址:http://stackoverflow.com/questions/9653457/locating-and-remedying-cause-of-large-heap-size

 


   @成鵬致遠

  (blogs:lcw.cnblogs.com

  (emailwwwlllll@126.com)

  (qq552158509)

相關文章
相關標籤/搜索