??之前,我們一直都在使用Android Device Monitor對我們的應(yīng)用進行各種分析悬包,也建立了很深厚的感情衙猪,而如今,Android Device Monitor 已在 Android Studio 3.1 中棄用布近,并已從 Android Studio 3.2 中移除垫释,也意味著它即將要退役,離我們越來越遠了撑瞧,為了紀(jì)念這位曾經(jīng)對App做出巨大貢獻的應(yīng)用棵譬,讓我們回顧一下它的事跡!
準(zhǔn)備工作
- 在Android SDK路徑下打開tools雙擊monitor打開Android Device Monitor
- 下載MAT工具并安裝
Android Device Monitor
打開后它的主頁面如圖一预伺,如果有些窗格沒有展示出來订咸,可以點擊window-Reset Perspective-Yes重置下配置,或者點擊window-Show View選擇自己想要展示的窗格
Devices
??設(shè)備列表如圖二所示酬诀,選擇某應(yīng)用后脏嚷,紅色框內(nèi)的圖標(biāo)就會點亮,供您使用瞒御,他們的具體信息從左到右介紹如下:
- Debug Process:調(diào)試進程父叙,該按鈕一直處于灰色狀態(tài)不能點擊
- Update Heap:更新堆信息,點擊后它葵腹,結(jié)果將會在Heap窗格中展示
- Dump HPROF file:獲取hprof文件(常用)高每,官方推薦使用新工具CPU Profiler
- Cause GC:垃圾回收
- Update Threads:更新線程信息,結(jié)果在Threads中展示
- Start Method Profiling:啟動方法分析践宴,官方推薦使用新工具CPU Profiler
- Stop Process:停止進程
- Screen Capture:屏幕截圖
- Dump View Hierarchy for UI Automator:視圖層級轉(zhuǎn)儲(常用)鲸匿,官方推薦使用新工具Layout Inspector,用Layout Inspector查看視圖層級時阻肩,如果您的設(shè)備沒有安裝Google Play商店且已獲得root權(quán)限才能看到正在運行的應(yīng)用带欢,否則,只能看到正在運行的可調(diào)試應(yīng)用烤惊。如果您想在非root手機上查看正在運行的不可調(diào)試應(yīng)用視圖乔煞,建議您使用Dump View Hierarchy for UI Automator嘗試一下
- Capture System Wide Trace:捕獲系統(tǒng)信息
- Reset adb:重置安卓調(diào)試橋
-
Start OpenGL Trace:開啟OpenGL跟蹤
Dump HPROF file
??此功能主要用來生成.hprof文件,對于該文件的分析柒室,還需要工具Eclipse Memory Analyzer打開才行渡贾。monitor生成的.hprof文件并不是標(biāo)準(zhǔn)的、MAT可識別的文件雄右,因此空骚,需要我們把.hprof轉(zhuǎn)成標(biāo)準(zhǔn)的文件后纺讲,才能使用MAT工具進行分析,轉(zhuǎn)換步驟如下:
- 打開命令行工具
- 輸入hprof-conv -z A.hprof B.hprof囤屹,如果提示命令hprof-conv用不了的話熬甚,請切換到android sdk/platform-tools后再操作
- A.hprof為轉(zhuǎn)換前的文件
- B.hprof為轉(zhuǎn)換后的文件
??在這里,我們創(chuàng)建一個項目肋坚,故意讓一個單例類SingleInstance持有SingleInstanceActivity對象導(dǎo)致內(nèi)存泄漏乡括,接著使用DDMS工具生成.hprof文件,然后再使用上面的命令換成標(biāo)準(zhǔn)的.hprof文件后智厌,我們就可以進入MAT的世界了诲泌!
該測試項目只有三個Java文件如下
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onSingleInstance(View view) {
Intent intent = new Intent(this, SingleInstanceActivity.class);
startActivity(intent);
}
}
SingleInstance.java
public class SingleInstance {
private static Context context;
private static SingleInstance singleInstance;
private SingleInstance() {
}
public static SingleInstance getInstance(Context ctx) {
if (singleInstance == null) {
context = ctx;
singleInstance = new SingleInstance();
}
return singleInstance;
}
}
SingleInstanceActivity.java
public class SingleInstanceActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_instance);
SingleInstance.getInstance(this);
}
}
??運行App后,先點擊Dump HPROF file一次獲取沒有產(chǎn)生內(nèi)存泄漏的unml.hprof文件峦剔,接著依序打開SingleInstanceActivity-點擊返回鍵档礁,在DDMS中頻繁點擊GC角钩,再繼續(xù)獲取有內(nèi)存溢出的ml.hprof文件吝沫,然后將unml.hprof轉(zhuǎn)換成unml_stantard.hprof文件,將ml.hprof轉(zhuǎn)換成ml_stantard.hprof文件递礼。
MAT
??使用MAT打開我們剛才生成的unml_stantard.hprof文件惨险,打開步驟:File->Open Heap Demp,打開后默認展示如圖三所示脊髓,這個時候我們點擊Histogram如圖四所示辫愉,然后在紅框這個地方輸入我們的包名敲回車如圖五所示,紅框這個地方顯示将硝,只存在一個實例恭朗,也就是MainActivity句各,同樣的操作牡拇,我們在ml_stantard.hprof看一下弛矛,ml_stantard的Histogram如圖六所示羔味,這個時候我們發(fā)現(xiàn)SingleInstanceActivity還存在呢排作,內(nèi)存泄漏也就產(chǎn)生了备恤,無論我們GC多少次蚓耽,由于該對象被單例對象持有栅葡,而單例對象生命周期和應(yīng)用一致误辑,所以導(dǎo)致SingleInstanceActivity不能回收沧踏。
最后,我們簡單總結(jié)一下整個操作流程如下:
- 啟動應(yīng)用
- 打開monitor巾钉,選擇應(yīng)用
- 點擊Dump HPROF file生成.hprof文件
- 打開懷疑內(nèi)存泄漏的頁面后翘狱,關(guān)閉,頻繁GC操作
- 再次生成.hprof文件
- 將兩個.hprof文件轉(zhuǎn)換成標(biāo)準(zhǔn)的文件
- 使用MAT工具打開.hprof文件
??其實砰苍,整個操作流程還是挺麻煩的潦匈,讀者朋友們了解一下就可以了踏烙,因為Google還提供了另一種更加便利的方式,想了解的朋友可以看一下上一篇文章Android性能優(yōu)化—內(nèi)存泄漏分析(一)