性能優化工具-LeakCanary

一、簡介
使用MAT來分析內存問題,有一些門檻,會有一些難度,並且效率也不是很高,對於一個內存泄漏問題,可能要進行多次排查和對比才能找到問題原因。 爲了能夠簡單迅速的發現內存泄漏,Square公司基於MAT開源了LeakCanary
二、使用
在app build.gradle 中加入引用:

dependencies {
	debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.2'
    implementation 'com.squareup.leakcanary:leakcanary-object-watcher-android:2.2'
    androidTestImplementation "com.squareup.leakcanary:leakcanary-android-instrumentation:2.2"
}

最新版本的LeakCanary不需要在Application初始化配置,可以直接使用。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        LeakThread leakThread = new LeakThread();
        leakThread.start();
    }

     class LeakThread extends Thread {
        @Override
        public void run() {
            try {
                Thread.sleep(6 * 60 * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ObjectWatcher objectWatcher = AppWatcher.INSTANCE.getObjectWatcher();
        objectWatcher.watch(this,"main");
    }
}

MainActivity存在內存泄漏,原因就是非靜態內部類LeakThread持有外部類MainActivity的引用,LeakThread中做了耗時操作,導致MainActivity無法被釋放。

它用於自動監控Activity執行onDestroy方法之後是否發生內存泄露,當前此例onDestroy加是多餘的,這裏只是爲了方便舉例,如果想要監控Fragment,在Fragment中添加如上的onDestroy方法是有用的。

運行程序,這時會在界面生成一個名爲Leaks的應用圖標。接下來不斷的切換橫豎屏,這時會閃出一個提示框,提示內容爲:“Dumping heap.”。再稍等片刻,內存泄漏信息就會通過Notification展示出來。
在這裏插入圖片描述
使用小結:
fragment同理

 protected void onDestroy() {
        super.onDestroy();
        ObjectWatcher objectWatcher = AppWatcher.INSTANCE.getObjectWatcher();
        objectWatcher.watch(this,"fragment");
    }

三、使用權限

1、 你的應用需要有寫SD權限,因爲LeakCanary需要生成hprof文件,保存在SD卡里面,因此你的應用要先申請權限

<!– SDCard中創建與刪除文件權限 –>
<uses-permission android:name=“android.permission.MOUNT_UNMOUNT_FILESYSTEMS”/>

<!– 向SDCard寫入數據權限 –>
<uses-permission android:name=“android.permission.WRITE_EXTERNAL_STORAGE”/>

四、原理介紹

4.1 觸發檢測

每次當Activity/Fragment執行完onDestroy生命週期,LeakCanary就會獲取到這個Activity/Fragment,然後初始化RefWatcher對它進行分析,查看是否存在內存泄漏。

4.2 判斷是否存在內存泄漏

首先嚐試着從ReferenceQueue隊列中獲取待分析對象(軟引用和弱引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果軟引用或弱引用所引用的對象被垃圾回收器回收,Java虛擬機就會把這個軟引用或弱引用加入到與之關聯的引用隊列中),如果不爲空,那麼說明正在被系統回收,如果直接就返回DONE,說明已經被系統回收了,如果沒有被系統回收,可能存在內存泄漏,手動觸發系統GC,然後再嘗試移除待分析對象,如果還存在,說明存在內存泄漏。

4.3 分析內存泄漏

確定有內存泄漏後,調用heapDumper.dumpHeap()生成.hprof文件目錄。HAHA 是一個由 square 開源的 Android 堆分析庫,分析 hprof 文件生成Snapshot對象。Snapshot用以查詢對象的最短引用鏈。找到最短引用鏈後,定位問題,排查代碼將會事半功倍。

在這裏插入圖片描述
整體流程如下:
在這裏插入圖片描述
總結:

LeakCanary對於內存泄漏的檢測非常有效,但也並不是所有的內存泄漏都能檢測出來。
所以說LeakCanary針對Activity/Fragment的內存泄漏檢測非常好用,但是對於特殊情況,還得配合Android Monitor + MAT 來分析。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章