Android性能優(yōu)化—內(nèi)存泄漏分析之DDMS和MAT(二)

??之前,我們一直都在使用Android Device Monitor對(duì)我們的應(yīng)用進(jìn)行各種分析,也建立了很深厚的感情,而如今,Android Device Monitor 已在 Android Studio 3.1 中棄用,并已從 Android Studio 3.2 中移除,也意味著它即將要退役,離我們?cè)絹碓竭h(yuǎn)了,為了紀(jì)念這位曾經(jīng)對(duì)App做出巨大貢獻(xiàn)的應(yīng)用,讓我們回顧一下它的事跡!

準(zhǔn)備工作

Android Device Monitor

打開后它的主頁面如圖一,如果有些窗格沒有展示出來,可以點(diǎn)擊window-Reset Perspective-Yes重置下配置,或者點(diǎn)擊window-Show View選擇自己想要展示的窗格


圖一.png
Devices

??設(shè)備列表如圖二所示,選擇某應(yīng)用后,紅色框內(nèi)的圖標(biāo)就會(huì)點(diǎn)亮,供您使用,他們的具體信息從左到右介紹如下:

  • Debug Process:調(diào)試進(jìn)程,該按鈕一直處于灰色狀態(tài)不能點(diǎn)擊
  • Update Heap:更新堆信息,點(diǎn)擊后它,結(jié)果將會(huì)在Heap窗格中展示
  • Dump HPROF file:獲取hprof文件(常用),官方推薦使用新工具CPU Profiler
  • Cause GC:垃圾回收
  • Update Threads:更新線程信息,結(jié)果在Threads中展示
  • Start Method Profiling:啟動(dòng)方法分析,官方推薦使用新工具CPU Profiler
  • Stop Process:停止進(jìn)程
  • Screen Capture:屏幕截圖
  • Dump View Hierarchy for UI Automator:視圖層級(jí)轉(zhuǎn)儲(chǔ)(常用),官方推薦使用新工具Layout Inspector,用Layout Inspector查看視圖層級(jí)時(shí),如果您的設(shè)備沒有安裝Google Play商店且已獲得root權(quán)限才能看到正在運(yùn)行的應(yīng)用,否則,只能看到正在運(yùn)行的可調(diào)試應(yīng)用。如果您想在非root手機(jī)上查看正在運(yùn)行的不可調(diào)試應(yīng)用視圖,建議您使用Dump View Hierarchy for UI Automator嘗試一下
  • Capture System Wide Trace:捕獲系統(tǒng)信息
  • Reset adb:重置安卓調(diào)試橋
  • Start OpenGL Trace:開啟OpenGL跟蹤


    圖二.png

Dump HPROF file

??此功能主要用來生成.hprof文件,對(duì)于該文件的分析,還需要工具Eclipse Memory Analyzer打開才行。monitor生成的.hprof文件并不是標(biāo)準(zhǔn)的、MAT可識(shí)別的文件,因此,需要我們把.hprof轉(zhuǎn)成標(biāo)準(zhǔn)的文件后,才能使用MAT工具進(jìn)行分析,轉(zhuǎn)換步驟如下:

  • 打開命令行工具
  • 輸入hprof-conv -z A.hprof B.hprof,如果提示命令hprof-conv用不了的話,請(qǐng)切換到android sdk/platform-tools后再操作
  • A.hprof為轉(zhuǎn)換前的文件
  • B.hprof為轉(zhuǎn)換后的文件
    ??在這里,我們創(chuàng)建一個(gè)項(xiàng)目,故意讓一個(gè)單例類SingleInstance持有SingleInstanceActivity對(duì)象導(dǎo)致內(nèi)存泄漏,接著使用DDMS工具生成.hprof文件,然后再使用上面的命令換成標(biāo)準(zhǔn)的.hprof文件后,我們就可以進(jìn)入MAT的世界了!
    該測(cè)試項(xiàng)目只有三個(gè)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);
    }
}

??運(yùn)行App后,先點(diǎn)擊Dump HPROF file一次獲取沒有產(chǎn)生內(nèi)存泄漏的unml.hprof文件,接著依序打開SingleInstanceActivity-點(diǎn)擊返回鍵,在DDMS中頻繁點(diǎn)擊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,打開后默認(rèn)展示如圖三所示,這個(gè)時(shí)候我們點(diǎn)擊Histogram如圖四所示,然后在紅框這個(gè)地方輸入我們的包名敲回車如圖五所示,紅框這個(gè)地方顯示,只存在一個(gè)實(shí)例,也就是MainActivity,同樣的操作,我們?cè)趍l_stantard.hprof看一下,ml_stantard的Histogram如圖六所示,這個(gè)時(shí)候我們發(fā)現(xiàn)SingleInstanceActivity還存在呢,內(nèi)存泄漏也就產(chǎn)生了,無論我們GC多少次,由于該對(duì)象被單例對(duì)象持有,而單例對(duì)象生命周期和應(yīng)用一致,所以導(dǎo)致SingleInstanceActivity不能回收。


圖三.png

圖四.png

圖五.png

圖六.png

最后,我們簡單總結(jié)一下整個(gè)操作流程如下:

  • 啟動(dòng)應(yīng)用
  • 打開monitor,選擇應(yīng)用
  • 點(diǎn)擊Dump HPROF file生成.hprof文件
  • 打開懷疑內(nèi)存泄漏的頁面后,關(guān)閉,頻繁GC操作
  • 再次生成.hprof文件
  • 將兩個(gè).hprof文件轉(zhuǎn)換成標(biāo)準(zhǔn)的文件
  • 使用MAT工具打開.hprof文件
    ??其實(shí),整個(gè)操作流程還是挺麻煩的,讀者朋友們了解一下就可以了,因?yàn)镚oogle還提供了另一種更加便利的方式,想了解的朋友可以看一下上一篇文章Android性能優(yōu)化—內(nèi)存泄漏分析(一)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容