一、什么是LeakCanary?

LeakCanary就是用来检测Android端内存泄漏的一个工具。能够检测Activity的泄漏

什么是内存泄漏?

Java 对象有时也会”长死不死“,GC 拿它没有办法,这种情况就是内存泄漏。造成这种情况的原因是:Java 对象被另一个生命周期更长对象持有,具有 可达性 ,这并不是我们想要的。

来自 <http://www.jianshu.com/p/3f1a1cc1e964>

内存泄漏的危害?

内存泄漏最终将导致内存溢出,也就是OOM,并且OOM发生在某一处,并不代表问题就是出在那里的,只是刚好有一块内存申请,此时内存又不够了才导致的,比较容易出现在申请比较大的内存的情况下。但是把这块申请的内存降低并不能从根本上解决问题。

这里有一个问题就是:内存的分配方式,分配位置,比如BitMap的分配,以及其他对象的分配?以及Activity对对象的持有,这个概念还不是很清晰。

github上的地址:https://github.com/square/leakcanary

一个原理的介绍内容在这里:

https://www.liaohuqiu.net/cn/posts/leak-canary/

https://www.liaohuqiu.net/cn/posts/leak-canary-read-me/

二、LeakCanary的工作原理是什么?

这三个都有讲解,并且还有直接通过源码来进行讲解的,后面可以针对这块,针对源码专门研究一下。

http://www.jianshu.com/p/a8900eb3de12

http://www.jianshu.com/p/5ee6b471970e

http://www.jianshu.com/p/3f1a1cc1e964

工作原理是:

LeakCanary会开启一个Service,这个Service能够在一个Activity被OnDestory之后,检测是否真的还有这个对象,如果还有,会尝试进行二次确认,如果这个对象还是没有被释放掉,则会获取当时的内存状态,生成一个heap的状态文件,然后分析文件,计算这个对象的GC ROOT的最短强引用路径,确定是否泄漏,如果有泄漏,Leak的APP就会有一条通知栏消息出现

检测流程图如下:

三、如何使用

1、在build.gradle中引入:

debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1' // or 1.4-beta1
    releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' // or 1.4-beta1
    testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' // or 1.4-beta1

或者,现在最新的1.5.1的也可以直接用:

dependencies{

compile'com.squareup.leakcanary:leakcanary-android:1.5.1'

}

2、同时,在Application的方法,在OnCreate中添加install

public class DemoApplication extends Application {
    @Override public void onCreate() {
        super.onCreate();
        LeakCanary.install(this);
    }
}

3、在添加之后,直接打出来应用的包,装上之后,会看到有一个附属应用出来,名字叫做Leaks

4、直接操作APP,如果发现有内存泄漏,则这个过程中会有通知栏提示,点击查看即可,可以将泄漏的信息分享,也可以将当时的heap dump的信息分享出来(但有可能这个heap dump不一定存在)

以检测出来的一个图为例:

LeakCanary的内存泄露提示一般会包含三个部分:

第一部分(LeakSingle类的sInstance变量)引用第二部分(LeakSingle类的mContext变量), 导致第三部分(MainActivity类的实例instance)泄露.

下方是一些更详细的原理的讲解:

1、不同的几种引用方式:强-软-弱-虚

2、LeakCanary这里,有一个原理的讲解叫做:

需要理解为什么要用WeakReference,因为GC的时候是不会对强引用的做处理,而软引用的是在内存不够用了才会被回收,而弱引用就是可以随时回收,所以需要用WeakReference对待检测的对象进行包裹引用,因为是弱引用的,因此在待检测对象调用了Destory或者Finish方法之后,被WeakReference引用的对象的生命周期结束,因为这个是弱引用,就会被GC检测到,这个时候GC会把该对象添加到ReferenceQueue中,如果GC结束该对象还是没有被加入到ReferenceQueue中,则说明可能存在内存泄漏,其实就是找到所有生命周期结束的对象,过滤掉会被回收的,剩下就是没有被回收的,然后会做二次GC,之后还是没有回收,就可以找到当时的内存状态,拿到不同对象的引用情况,得到一个hprof的文件,之后就能找到最短强引用的路径。

解决内存泄漏,通过以下方式:

然后我们需要解决:如何得到未被回收的对象。ReferenceQueue+WeakReference+手动调用 GC可实现这个需求。

  • WeakReference 创建时,传入一个 ReferenceQueue 对象。当被 WeakReference 引用的对象的生命周期结束,一旦被 GC 检查到,GC 将会把该对象添加到 ReferenceQueue 中,待ReferenceQueue处理。当 GC 过后对象一直不被加入 ReferenceQueue,它可能存在内存泄漏。

获得未被回收的 Object

  • 找到了未被回收的对象,如何确认是否真的内存泄漏?这里可以将问题转换为:未被回收的对象,是否被其他对象引用?找出其最短引用链。VMDebug + HAHA 完成需求。
    VM 会有堆内各个对象的引用情况,并能以hprof文件导出。HAHA 是一个由 square 开源的 Android 堆分析库,分析 hprof 文件生成Snapshot对象。Snapshot用以查询对象的最短引用链。

解析hprof

  • 找到最短引用链后,定位问题,排查代码将会事半功倍。

如下泳道图分析, LeakCanary 各个模块如何配合达到检测目的。

来自 <http://www.jianshu.com/p/3f1a1cc1e964>

【Android内存泄漏检测】LeakCanary使用总结的更多相关文章

  1. Android内存泄漏检测利器:LeakCanary

    Android内存泄漏检测利器:LeakCanary MAR 28TH, 2016 是什么? 一言以蔽之:LeakCanary是一个傻瓜化并且可视化的内存泄露分析工具 为什么需要LeakCanary? ...

  2. android 内存泄漏检测工具 LeakCanary 泄漏金丝雀

    韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com 内存泄漏检测工具 android 内存泄漏检测工具 ======== 内存泄漏 就是  无用的对 ...

  3. Android 内存泄漏检测工具 LeakCanary(Kotlin版)的实现原理

    LeakCanary 是一个简单方便的内存泄漏检测框架,做 android 的同学基本都收到过 LeakCanary 检测出来的内存泄漏.目前 LeakCanary 最新版本为 2.7 版本,并且采用 ...

  4. Android 性能优化之内存泄漏检测以及内存优化(中)

    https://blog.csdn.net/self_study/article/details/66969064 上篇博客我们写到了 Java/Android 内存的分配以及相关 GC 的详细分析, ...

  5. 为什么各大厂自研的内存泄漏检测框架都要参考 LeakCanary?因为它是真强啊!

    请点赞关注,你的支持对我意义重大. Hi,我是小彭.本文已收录到 GitHub · AndroidFamily 中.这里有 Android 进阶成长知识体系,有志同道合的朋友,关注公众号 [彭旭锐] ...

  6. Android内存泄漏的检测流程、捕捉以及分析

    https://blog.csdn.net/qq_20280683/article/details/77964208 Android内存泄漏的检测流程.捕捉以及分析 简述: 一个APP的性能,重度关乎 ...

  7. android 内存泄漏,以及检测方法

    1.为什么会产生内存泄漏 当一个对象已经不需要再使用本该被回收时,另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这就产生了内存泄漏. 2.内 ...

  8. 利用Android Studio、MAT对Android进行内存泄漏检测

    利用Android Studio.MAT对Android进行内存泄漏检测 Android开发中难免会遇到各种内存泄漏,如果不及时发现处理,会导致出现内存越用越大,可能会因为内存泄漏导致出现各种奇怪的c ...

  9. LeakCanary 来检查 Android 内存泄漏

    LeakCanary 来检查 Android 内存泄漏

随机推荐

  1. 机器学习进阶-图片基本处理-ROI区域 1.img[0:200, 0:200]截取图片 2.cv2.split(对图片的颜色通道进行拆分) 3. cv2.merge(将颜色通道进行合并) 4 cur_img[:, :, 0] = 0 使得b通道的颜色数值为0

    1. 截取图片的部分区域img[0:200, 0:200], 读入的图片是ndarray格式 2. b, g, r = cv2.split(img)  # 对图片的颜色通道进行拆分 3.img = c ...

  2. 使用ssh密钥登录虚拟主机里的另一台主机报警的解决方案

    提示:Address 192.168.*.* maps to localhost, but this does not map back to the address - POSSIBLE BREAK ...

  3. mybatisGenerator自动生成pojo、dao、xml文件

    一.简介: mybatisGenerator是一款自动生成文件工具.本文使用idea2017.3.1来进行操作. 二.文件生成之后的项目结构: 三.开始生成步骤: 1.使用idea生成maven的结构 ...

  4. netty为啥要二次开发

    很早之前就看过李林峰写的netty的书,但是感觉没有直接用到还是理解不够深入,现在的公司有两套自己基于Netty开发的系统,感觉才真正理解为啥要这么做 借用别人文章回顾下 https://www.cn ...

  5. Linux命令:history

    显示历史(执行过的)命令. history [n] history -c history -d offset history -anrw [filename] history -p arg [arg ...

  6. VUE 计算属性 vs 侦听属性

    计算属性 vs 侦听属性 Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性.当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 ...

  7. Mybatis高级应用-2

    文章内容简介 1.回顾 2.Mybatis配置文件解析 3.Mybatis映射文件解析 ResultMap标签使用 自定义返回值处理(Map) 关联映射 主键映射 一.回顾 Mybatis是ORM(o ...

  8. python小实例一:简单爬虫

    本文所谓的爬虫就是通过本地远程访问url,然后将url的读成源代码形式,然后对源代码进行解析,获取自己需要的数据,相当于简单数据挖掘.本文实现的是将一个网页的图片爬出保存到本地的过程,例子很简单,用的 ...

  9. 点击对应不同name的button,显示不同name的弹窗(弹窗功能)

    (通过html5方法自定义属性选择,因此会有兼容性,此方法可适用移动端) 将button的name,与弹窗的name设为变量,作为参数传递. Button的name可以是自定义name,HTML5自定 ...

  10. 更新package.json中的dependencies依赖到最新版本 -

    我们从别人那里下载一个项目 ,通过package.json里面的依赖 npm  install 来安装所需要的各个包 但是 有可能项目很老,我们一个个更新又很麻烦所以 https://blog.csd ...