博客
关于我
LeakCanary 中文使用说明
阅读量:667 次
发布时间: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/

    你可能感兴趣的文章
    解决:angularjs radio默认选中失效问题
    查看>>
    windows环境下安装zookeeper(仅本地使用)
    查看>>
    缓冲区溢出实例(一)--Windows
    查看>>
    Hadoop学习笔记—Yarn
    查看>>
    Jenkins - 部署在Tomcat容器里的Jenkins,提示“反向代理设置有误”
    查看>>
    wxWidgets源码分析(3) - 消息映射表
    查看>>
    wxWidgets源码分析(5) - 窗口管理
    查看>>
    wxWidgets源码分析(8) - MVC架构
    查看>>
    wxWidgets源码分析(9) - wxString
    查看>>
    [梁山好汉说IT] 梁山好汉和抢劫银行
    查看>>
    [源码解析] 消息队列 Kombu 之 基本架构
    查看>>
    [源码分析] 消息队列 Kombu 之 启动过程
    查看>>
    wx.NET CLI wrapper for wxWidgets
    查看>>
    Silverlight for linux 和 DLR(Dynamic Language Runtime)
    查看>>
    ASP.NET MVC Action Filters
    查看>>
    Powershell中禁止执行脚本解决办法
    查看>>
    OO_Unit2 多线程电梯总结
    查看>>
    git clone 出现fatal: unable to access ‘https://github 错误解决方法
    查看>>
    04_Mysql配置文件(重要参数)
    查看>>
    python 加密算法及其相关模块的学习(hashlib,RSA,random,string,math)
    查看>>