博客
关于我
LeakCanary 中文使用说明
阅读量:668 次
发布时间:2019-03-16

本文共 3596 字,大约阅读时间需要 11 分钟。

LeakCanary中文使用说明


Android 和 Java 内存泄露检测

“千里之堤,毁于蚁穴。” —— 《韩非子·喻老》

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?

使用 LeakCanary 可以帮助开发者找到那些被意外地保留引用的对象,从而提前发现潜在的内存泄露问题。以下是一些使用场景:

  • 监控 Activity 示例:确保活动在 onDestroy 被正确释放。
  • 监控 Fragment 示例:在 onDestroy 方法中观察 Fragment 的引用。
  • 手动监控其他对象:通过 RefWatcher 逐个观察需要回收的对象。

LeakCanary 的工作机制

LeakCanary 的核心原理是通过观察对象的生命周期,检测潜在的内存泄露问题。它的工作流程如下:

  • 注册观察:使用 RefWatcher.watch() 对要观察的对象注册监控。
  • 引用检查:在后台线程中周期性地检查对象引用是否已被回收。如果未被回收,触发 GC。
  • 堆内存转储:在检测到内存泄露前,将 heap 内存转储到 .hprof 文件。
  • 分析文件:通过 HeapAnalyzerService 对转储的内存文件进行分析,定位泄露来源。
  • 展示泄露原因:将分析结果以通知的形式展示给开发者。

  • 复制 leak trace?

    在 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

    通过分享按钮,你可以将这些信息直接分享出去。


    SDK 导致的内存泄露

    随着 Android SDK 的不断更新,厂商 ROM 中的内存泄露问题逐渐得到修复。然而,当出现新的内存泄露时,开发者通常很难找到真正的原因。

    LeakCanary 提供了一个已知问题的忽略列表。如果你发现了新的内存泄露问题,请附上以下信息:

    • leak trace:泄露发现的日志
    • Reference Key:泄露报告中的唯一标识符
    • 设备型号:你使用的设备模型
    • SDK 版本:相关的 SDK 版本信息
    • 堆转储文件:提供隐藏文件的链接(如果有)

    对于最新发布的 Android 版本,这一点尤为重要。你有机会帮助整个 Android 社区发现新的内存泄露问题。


    leak trace 之外

    有时,Logcat 中的 leak trace 不够详细。通过分析堆转储文件,你可以更深入地了解问题所在。以下是一些操作步骤:

  • 查找所有 KeyedWeakReference 实例。
  • 检查 Key 字段。
  • 找到与 leak trace 中 Reference Key 匹配的 KeyedWeakReference。
  • 获取 referent 字段,即泄露的对象。
  • 检查 GC root 的最短强引用路径,以确定泄露原因。

  • 自定义

    UI 样式

    你可以根据自己的需求自定义 LeakCanary 的 UI 样式。例如,在你的 APP 资源中替换默认的图标和标签:

    drawable-hdpi/__leak_canary_icon.pngdrawable-mdpi/__leak_canary_icon.png...

    保存 leak trace

    默认情况下,DisplayLeakActivity 会在 APP 目录中保存 7 个 heap dump 文件。你可以通过修改资源文件 来改变保存数量:

    20

    上传 leak trace 到服务器

    你可以创建一个自定义服务,用于将 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

    你可以根据需求定制 RefWatcher:

    public class DebugExampleApplication extends ExampleApplication {    protected RefWatcher installLeakCanary() {        return LeakCanary.install(app, LeakUploadService.class);    }

    别忘了在 AndroidManifest.xml 中注册服务:


    通过以上方法,你可以更好地监控和预防 Android 应用的内存泄露问题。

    转载地址:http://dneqz.baihongyu.com/

    你可能感兴趣的文章
    Rust异步浅谈
    查看>>
    man工具
    查看>>
    【网络加速】TensorRT7-开发指南中文_Plus版【1】
    查看>>
    SaltStack about The Top File 使用知识介绍
    查看>>
    AttributeError: ‘list‘ object has no attribute ‘astype‘
    查看>>
    网络协议和支持(一)、uuid模块
    查看>>
    numpy.vstack
    查看>>
    numpy.frombuffer()
    查看>>
    文件结束符EOF
    查看>>
    Latex 错误集合
    查看>>
    Python的一个报错——OSError: [Errno 22] Invalid argument
    查看>>
    Python的内置函数(四十一)、 index()
    查看>>
    Python的内置函数(四十二)、 numel()
    查看>>
    python中的os.path.dirname与os.path.dirname(__file__)的用法
    查看>>
    Python 代码占多行
    查看>>
    TypeError: string indices must be integers
    查看>>
    卷积神经网络的工程技巧总结
    查看>>
    OSError: [Errno 22] Invalid argument: ‘D:\test\x07‘
    查看>>
    Python的内置函数(十六)、strip()
    查看>>
    Python字符串操作之字符串分割与组合
    查看>>