Square公司開發
可以直接在手機端查看內存泄露的工具
實現原理:本質上還是用命令控制生成hprof文件分析檢查內存泄露,然后發送通知。
Application
? ???install()
LeakCanary
? ???androidWatcher()
RefWatcher
? ???new AndroidWatcherExecutor() --->dumpHeap()/analyze()(--->runAnalysis())-------->Hprof文件分析
? ???new AndroidHeapDumper()
? ???new ServiceHeapDumpListener
添加LeakCanary依賴包
https://github.com/square/leakcanary
在主模塊app下的build.gradle下添加如下依賴:
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
開啟LeakCanary
-
添加Application子類
首先創建一個ExampleApplication,該類繼承于Application,在該類的onCreate方法中添加如下代碼開啟LeakCanary監控:
LeakCanary.install(this);
-
在配置文件中注冊ExampleApplication
在AndroidManifest.xml中的application標簽中添加如下信息:
android:name=".ExampleApplication"
這個時候安裝應用到手機,會自動安裝一個Leaks應用,如下圖:
- **制造一個內存泄漏的點 **
建立一個ActivityManager類,單例模式,里面有一個數組用來保存Activity:
package com.example.android.sunshine.app;
import android.app.Activity;
import android.util.SparseArray;
import android.view.animation.AccelerateInterpolator;
import java.util.List;
public class ActivityManager {
private SparseArray<Activity> container = new SparseArray<Activity>();
private int key = 0;
private static ActivityManager mInstance;
private ActivityManager(){}
public static ActivityManager getInstance(){
if(mInstance == null){
mInstance = new ActivityManager();
}
return mInstance;
}
public void addActivity(Activity activity){
container.put(key++,activity);
}
}
然后在DetailActivity中的onCreate方法中將當前activity添加到ActivityManager的數組中:
package com.example.android.sunshine.app;
import android.app.Activity;
import android.util.SparseArray;
import android.view.animation.AccelerateInterpolator;
import java.util.List;
public class ActivityManager {
private SparseArray<Activity> container = new SparseArray<Activity>();
private int key = 0;
private static ActivityManager mInstance;
private ActivityManager(){}
public static ActivityManager getInstance(){
if(mInstance == null){
mInstance = new ActivityManager();
}
return mInstance;
}
public void addActivity(Activity activity){
container.put(key++,activity);
}
}
我們從首頁跳轉到詳情頁的時候會進入DetailActivity的onCreate的方法,然后就將當前activity添加到了數組中,當返回時,我們沒把他從數組中刪除。再次進入的時候,會創建新的activity 并添加到數組中,但是之前的activity仍然被引用,無法釋放,但是這個activity不會再被使用,這個時候就造成了內存泄漏。我們來看看LeakCanary是如何報出這個問題的。
演示
解析的過程有點耗時,所以需要等待一會才會在Leaks應用中,當我們點開某一個信息時,會看到詳細的泄漏信息: