什么是LeakCanary
LeakCanary是# square公司推出的專為Android設(shè)計(jì)的內(nèi)存泄露檢測(cè)庫(kù)
如何集成
官方github地址:https://github.com/square/leakcanary
使用步驟很簡(jiǎn)單佩谣,下面簡(jiǎn)單把官方步驟翻譯一下
1,在build.gradle文件中引入依賴
dependencies {
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5.4'
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'
}
2,在Application的onCreate方法中引入
public class ExampleApplication extends Application {
@Override public void onCreate() {
super.onCreate();
if (LeakCanary.isInAnalyzerProcess(this)) {
// 這個(gè)線程是專門給LeakCanary做堆內(nèi)存分析的
// 在這里不要寫app初始化代碼
return;
}
LeakCanary.install(this);
// 在這里寫你app的初始化代碼
}
}
到目前為止铃肯,LeakCanary已經(jīng)集成到你的項(xiàng)目中
如果APP的Android編譯版本>=4.0版本港准,那么LeakCanary已經(jīng)可以自動(dòng)檢測(cè)內(nèi)存泄露了
因?yàn)?.0之后Application提供了registerActivityLifecycleCallbacks方法,可以給全局的activity生命周期加入回調(diào),至于原因叫挟,我們?cè)谠创a解析篇進(jìn)行分析
模擬一個(gè)內(nèi)存泄露
一個(gè)比較常見(jiàn)的場(chǎng)景:
Handler作為成員變量接受一個(gè)匿名內(nèi)部類的實(shí)現(xiàn)旁趟,onCreate方法中昼激,發(fā)布一個(gè)延時(shí)任務(wù),60秒后執(zhí)行
锡搜,然后手動(dòng)關(guān)閉Activity
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
Handler handler = new Handler(){
@Override
public void dispatchMessage(Message msg) {
super.dispatchMessage(msg);
//do something
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler.sendEmptyMessageDelayed(0,60 * 1000);
}
}
然后屏幕會(huì)發(fā)出一個(gè)提示框
然后再通知欄會(huì)收到一條通知橙困,如果是第一次使用,會(huì)先請(qǐng)求寫入權(quán)限耕餐,點(diǎn)擊凡傅,并允許
然后過(guò)一段時(shí)間,通知欄會(huì)出現(xiàn)新的通知肠缔,點(diǎn)進(jìn)去就是內(nèi)存泄漏的引用鏈
我們看到MessageQueue中的mMessages中的target持有MainActivity的引用夏跷,這個(gè)target就是我們MainActivity當(dāng)中的匿名實(shí)現(xiàn)的成員變量Handler,從而得知內(nèi)存泄露的原因
LeakCanary在檢測(cè)到內(nèi)存泄露的同時(shí)明未,除了彈出通知槽华,還會(huì)將堆內(nèi)存dump成hprof文件放在我們的應(yīng)用所屬的file文件夾下面(十分鐘之內(nèi),只會(huì)寫入一次)
如果我們想要詳細(xì)的分析趟妥,就需要借助MAT工具猫态,來(lái)分析hprof文件
hprof文件
轉(zhuǎn)換成MAT可識(shí)別的文件
cd到sdk/tools的路徑下,執(zhí)行命令 hprof-conv hprof路徑 輸出路徑
得到mat可識(shí)別的文件
MAT
下載地址:http://www.eclipse.org/mat/downloads.php
win版安裝之后如下,點(diǎn)擊運(yùn)行MemoryAnalyzer.exe
點(diǎn)擊右上角菜單File - OpenHeapDump - 剛剛轉(zhuǎn)換后的hprof文件
右鍵這個(gè)條目 —— Path to GC roots —— with all references
referent是LeakCanary保存的對(duì)Activity的引用
this$0就是內(nèi)部類所自動(dòng)保留的一個(gè)指向所在外部類的引用
很明顯是this$0導(dǎo)致了我們內(nèi)存的泄露懂鸵,也就是mMessages中的target偏螺,也就是Handler