一. 简介
LeakCanary是Square开源的一个分析内存泄漏的神器,它使用简单,功能强大,当程序出现内存泄漏时会在通知栏给出提示,
image.png
点击提示会进入泄漏详情页面
image.png
二. 使用
1. gradle中引用依赖
dependencies {
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.2'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.2'
}
2. 在Application中设置
MyApplication
//Kotlin
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
setupLeakCanary()
}
fun setupLeakCanary() {
if (LeakCanary.isInAnalyzerProcess(this)) {
return
}
enableStrictMode()
LeakCanary.install(this)
}
fun enableStrictMode() {
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build())
}
}
泄漏示例:
//Kotlin
class TestActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_test)
start.setOnClickListener { v -> ruun() }
}
fun ruun() {
object: AsyncTask<Void, Void, Void>() { //匿名内部类
override fun doInBackground(vararg params: Void?): Void? {
SystemClock.sleep(20000)
return null
}
}.execute()
}
}
也可以使用LeakCanary监控Fragment的泄漏情况
public abstract class BaseFragment extends Fragment {
@Override public void onDestroy() {
super.onDestroy();
RefWatcher refWatcher = ExampleApplication.getRefWatcher(getActivity());
refWatcher.watch(this);
}
}
3. 工作机制
-
RefWatcher.watch() 创建一个 KeyedWeakReference 到要被监控的对象。
-
然后在后台线程检查引用是否被清除,如果没有,调用GC。
-
如果引用还是未被清除,把 heap 内存 dump 到 APP 对应的文件系统中的一个 .hprof 文件中。
-
在另外一个进程中的 HeapAnalyzerService 有一个 HeapAnalyzer 使用HAHA 解析这个文件。
-
得益于唯一的 reference key, HeapAnalyzer 找到 KeyedWeakReference,定位内存泄露。
-
HeapAnalyzer 计算 到 GC roots 的最短强引用路径,并确定是否是泄露。如果是的话,建立导致泄露的引用链。
-
引用链传递到 APP 进程中的 DisplayLeakService, 并以通知的形式展示出来。
网友评论