本文共 3596 字,大约阅读时间需要 11 分钟。
“千里之堤,毁于蚁穴。” —— 《韩非子·喻老》
LeakCanary 是专为 Android 开发的内存泄露检测工具。它能帮助开发者自动检测内存泄露问题,特别是在调试和 debug 的阶段。
在你的 build.gradle
中添加 LeakCanary 的依赖:
dependencies { debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'}
接下来,在应用的 Application
类中安装 LeakCanary:
public class ExampleApplication extends Application { @Override public void onCreate() { super.onCreate(); LeakCanary.install(this); }}
这样,在 debug 版本中,LeakCanary 就会自动检测活动对象的内存泄露,并在发现泄露时显示通知。
使用 LeakCanary 可以帮助开发者找到那些被意外地保留引用的对象,从而提前发现潜在的内存泄露问题。以下是一些使用场景:
onDestroy
被正确释放。onDestroy
方法中观察 Fragment 的引用。RefWatcher
逐个观察需要回收的对象。LeakCanary 的核心原理是通过观察对象的生命周期,检测潜在的内存泄露问题。它的工作流程如下:
RefWatcher.watch()
对要观察的对象注册监控。.hprof
文件。HeapAnalyzerService
对转储的内存文件进行分析,定位泄露来源。在 Logcat 中,你可以看到类似这样的 leak trace:
In com.example.leakcanary:1.0:1 com.example.leakcanary.MainActivity has leaked:- GC ROOT thread java.lang.Thread. (named 'AsyncTask #1') references com.example.leakcanary.MainActivity$3.this$0 (anonymous class extends android.os.AsyncTask) leaks com.example.leakcanary.MainActivity instance Reference Key: e71f3bf5-d786-4145-8539-584afaecad1d Device: Genymotion generic Google Nexus 6 - 5.1.0 - API 22 - 1440x2560 vbox86p Android Version: 5.1 API: 22 Durations: watch=5086ms, gc=110ms, heap dump=435ms, analysis=2086ms
通过分享按钮,你可以将这些信息直接分享出去。
随着 Android SDK 的不断更新,厂商 ROM 中的内存泄露问题逐渐得到修复。然而,当出现新的内存泄露时,开发者通常很难找到真正的原因。
LeakCanary 提供了一个已知问题的忽略列表。如果你发现了新的内存泄露问题,请附上以下信息:
对于最新发布的 Android 版本,这一点尤为重要。你有机会帮助整个 Android 社区发现新的内存泄露问题。
有时,Logcat 中的 leak trace 不够详细。通过分析堆转储文件,你可以更深入地了解问题所在。以下是一些操作步骤:
你可以根据自己的需求自定义 LeakCanary 的 UI 样式。例如,在你的 APP 资源中替换默认的图标和标签:
drawable-hdpi/__leak_canary_icon.pngdrawable-mdpi/__leak_canary_icon.png...
默认情况下,DisplayLeakActivity 会在 APP 目录中保存 7 个 heap dump 文件。你可以通过修改资源文件 来改变保存数量:
20
你可以创建一个自定义服务,用于将 leak trace 和 heap dump 上传到你的服务器。例如:
public class LeakUploadService extends DisplayLeakService { @Override protected void afterDefaultHandling(HeapDump heapDump, AnalysisResult result, String leakInfo) { if (!result.leakFound || result.excludedLeak) { return; } myServer.uploadLeakBlocking(heapDump.heapDumpFile, leakInfo); }}
确保在 release 版本中 Disble RefWatcher:
public class ExampleApplication extends Application { private RefWatcher refWatcher; public static RefWatcher getRefWatcher(Context context) { ExampleApplication application = (ExampleApplication) context.getApplicationContext(); return application.refWatcher; } @Override public void onCreate() { super.onCreate(); refWatcher = RefWatcher.DISABLED; }}
你可以根据需求定制 RefWatcher:
public class DebugExampleApplication extends ExampleApplication { protected RefWatcher installLeakCanary() { return LeakCanary.install(app, LeakUploadService.class); }
别忘了在 AndroidManifest.xml 中注册服务:
通过以上方法,你可以更好地监控和预防 Android 应用的内存泄露问题。
转载地址:http://dneqz.baihongyu.com/