標籤:
轉載請註明出處 http://www.cnblogs.com/weiwangnuanyang/p/5703702.html
如果只是想確定一下某一個情境是否有記憶體流失,AndroidStadio的控制台就有一個好工具,反覆操作觀察曲線是否上揚,如果曲線上揚則說明記憶體流失
點擊旁邊第三個按鈕也可以產生hprof檔案。不過本人比較習慣用Eclipse,這裡就以Eclipse為例啦。
下面就來重點介紹一下如何利用Memory Analysis(Eclipse的一個外掛程式,具體安裝方式請移步度娘) 產生 和 分析 hprof檔案。
1. 產生hprof檔案。
產生hprof檔案很簡單,在Eclipse的DDMS視圖內,點擊你需要調試的進程,然後點擊[DUMP HPROF FILE]按鈕就好啦。
對於記憶體流失問題一般是需要對比分析的,所以如果沒有自動化測試環境的話,手動測試可以在進入app時存一個hprof檔案,
然後開始反覆測試泄漏的情境20+次,存一個hprof檔案,再反覆操作20+次,再存一個hprof檔案。
2. 簡單介紹。
下面是開啟一個hprof檔案後的概覽視圖。
從此概覽視圖中我們可以以此看到
Details(細節):展示了總大小,classes大小,objects大小, classloader 數量;unreachable objects histogram(可被回收對象柱狀圖);
Biggest Objects by Retained Size(佔用記憶體最大對象餅狀圖);
Histrogram(柱狀圖):列舉每個類的對象個數;
Dominator Tree(支配樹): 列舉最大的對象,和因為類而引起的不能回收的對象佔用空間大小;
Top Consumers(最大的消費者): 列舉佔用記憶體最大的對象的餅圖;
Duplicate Classes:檢測由多個類載入器載入的類;
Leak Suspects:包括一個簡單的泄漏分析和一個系統概述;
Top Components: 列舉在堆中大小大於總大小1%的組件,以class loader 分類(system class loader,PathClassLoader,DexClassLoader);
Component Report: 分析屬於common root package 或者 class loader的對象。
面板上面還有一些按鈕提供了根據地址搜對象,查看線程詳細資料,產生報表等功能。具體的大家點點看看就ok了。
3. 分析hprof檔案實戰。
以本人有限的分析記憶體流失的經驗來看,Memory Analysis提供的Leak Suspects往往都是不準確的,它的分析是基於類的對象在記憶體中佔用的總大小,
總是把一些系統類別比如byte列舉在第一位。就像下面這樣。
所以真正的有效分析還得靠自己。
要解決java記憶體流失的問題,首先要瞭解java中哪些情況會造成記憶體流失,具體請移步 http://www.cnblogs.com/weiwangnuanyang/p/5704596.html ;
分析記憶體問題,一個非常有效方法就是對比開始測試和結束測試時的類的個數。然後再分析這些類的參考關聯性。
下面就以一個執行個體來說一下。
第一步:產生兩個檔案並開啟,如下有17:55:55和18:00:29的兩份檔案。
第二步:開啟第二個檔案的類柱狀圖。
開啟以後是這樣的:
第三步:點擊Histogram上面的對比按鈕,與另一份檔案做對比。
這時候得到的結果是這樣的:
第四步:在<Regex>的輸入框裡輸入你的包名關鍵字,篩選出你自己的類,過濾掉系統類別。
這時候那些類泄漏了就非常明晰了。反覆操作n次就增加了n+個的類多半都是有問題的。
第五部:分析這些類的參考關聯性。在這個對比表裡點擊右鍵是沒有效果的,你需要開啟一個新的Histogram視圖,同樣用你的包名篩選出你寫的類。
然後選中一個點擊右鍵,這時候會出來一個菜單,菜單中前三項分別表示對象的參考關聯性,類的參考關聯性,類的回收路徑。
我們選擇類的Merge Shortest Path to GC Root(最短回收路徑)來看一下,點開以後的結果是這樣的:
首先可以看到有一大片InnerReceiver,這個肯定是有問題的,點開其中一個可以看到最後一個我們自己的類是BNavigator,點開這個類可以看到它註冊了
廣播但是沒有反註冊。
然後再看一下其他沒有回收的對象,下面這個是因為MapController引用了CarNaviAcitity的Context,而MapController是一個Map的key.
這裡有兩個問題需要考慮,其一是MapController作為key是否是合適的,當它作為key時是否在無用時及時從Map中移出;其二是MapController引用了CarNaviActivity的
Context,而不是ApplicationContext,這是造成anroid的Activity泄漏的一個主要原因。
再來看SurfaceView也是引了Activity的Context.
對於其他類的分析類似,在此不一一列舉了。
【原創】android記憶體管理-hprof檔案