Android开发:LeakCanary--检测所有的内存泄漏
2016-02-03 23:00
225 查看
没人喜欢OutOfMemoryError
在Square的注册过程中,我们在bitmap上 绘制了一个用户的签名。这个bitmap和设备的屏幕大小相当,在创建它的时候,我遇到了相当数量的OOM导致的崩溃。我们试过了几种方法,没有一个解决了我们的问题:
使用
Bitmap.Config.ALPHA_8(签名是不需要颜色的)
捕获
OutOfMemoryError,触发垃圾回收然后重试几次(从GCUtils 获得的启发)
我们没有考虑过将bitmap分配在堆内存之外,那个时候Fresco 还没出现。
我们看待问题的方式是不对的
bitmap的大小本身不是什么问题。当内存快要满了的时候,OOM随时随地都可能发生。尤其是在创建大对象的时候更容易发生,比如bitmap。OOM一般代表着更深层次的问题:内存泄漏。
什么是内存泄漏?
有些对象只有有限的生命周期。当它们的任务完成之后,它们将被垃圾回收。如果在对象的生命周期本该结束的时候,这个对象还被一系列的引用,这就会导致内存泄漏。随着泄漏的累积,app将消耗完内存。比如,在
Activity.onDestroy()被调用之后,view树以及相关的bitmap都应该被垃圾回收。如果一个正在运行的后台线程继续持有这个Activity的引用,那么相关的内存将不会被回收,这最终将导致
OutOfMemoryError崩溃。
寻找内存泄漏
寻找内存泄漏是一个人工操作的过程,在Raizlabs的 Wrangling Dalvik 系列中描述得很清楚。下面是关键的步骤:
通过 Bugsnag, Crashlytics, 或者 Developer Console了解OOM
主动重现问题。你可能需要买或者借或者偷一个遭遇了崩溃的特殊设备(并不是所有的设备上都会发生内存泄漏!)。你还需要找出是什么串在一起导致了内存泄漏。
当OOM出现时进行堆转储(dump the heap)(这里介绍了如何做).
使用MAT或YourKit内存检测工具检测内存的变化,并找出哪个对象应该被垃圾回收;
从那个对象到GC roots推断最短的强引用路径;
在路径中找出不存在的引用,并修复memory leak;
要是有一个库可以为你做完所有的事情,让你专注于修复内存泄漏的问题,那该有多好。
LeakCanary介绍
LeakCanary 是一个开源的在debug版本中检测内存泄漏的java库。让我们来看看一个cait的例子:
RefWatcher实例,然后给它一个对象让它观察:
结论
在启用LeakCanary之后,我们发现和修复了许多内存泄漏的问题。我们甚至发现了一些 Android SDK中的泄漏。结果是非常令人惊奇的,我们现在减少了94%的oom崩溃问题。
相关链接:
LeakCanary 中文使用说明:http://www.liaohuqiu.net/cn/posts/leak-canary-read-me/。
一个非常简单的 LeakCanary demo: https://github.com/liaohuqiu/leakcanary-demo
相关文章推荐
- Androidx学习笔记(49)--- Activity的跳转
- Androidx学习笔记(48)--- 创建Activity
- Androidx学习笔记(47)--- 借助xUtils实现下载
- Androidx学习笔记(46)--- 用进度条显示下载进度
- Android开发学习之路--Activity之生命周期
- Androidx学习笔记(45)--- 获取文件的后缀名(java基本语法)
- Android开发学习之路--Activity之生命周期
- 如何更好的设计android图标,拉伸不变形等等系列优点,而且减小apk大小
- Androidx学习笔记(44)--- 多线程断点续传(Android项目)
- 预览Android layouts, custom views和animations的插件
- Android Studio 安装genymotion 和VCS
- Android 5.0五大安全特性
- Android获取唯一设备号
- 解决 RecyclerView 在Android Studio已经导入情况下还无法实例引用问题
- Android studio 插件----android中xml tools属性详解
- Android manifest
- Android 自定义属性
- Android高手进阶——Adapter深入理解与优化
- Android 框架练成 教你打造高效的图片加载框架(转)
- android 单元测试简单方法及错误处理