LeakCanary:检测你APP所有的内存泄露
LeakCanary:检测你APP所有的内存泄露
java.lang.OutOfMemoryError
at android.graphics.Bitmap.nativeCreate(Bitmap.java:-2)
at android.graphics.Bitmap.createBitmap(Bitmap.java:689)
at com.squareup.ui.SignView.createSignatureBitmap(SignView.java:121)
1. 没人喜欢OOM这个Crash
在Square注册用户中,我们在以屏幕大小的bitmap的缓存中绘制用户的签名。而当我们创建这个bitmap的时候经常会出现OOM,
我们尝试了一些方法,但是都没有解决。
比如:
1.使用bitmap的Bitmap.Config.ALPHA_8
2.捕获OOM的异常,然后出发GC来回收,然后再重新创建
3.我们没有想到去收集bitmap的java堆内存。
2.我们曾以错误的方式来看待它。
问题并不在bitmap的大小上,当内存快满的时候,肯定会抛出OOM的,当你试图创建大的对象时,会经常抛出OOM异常。而出现OOM更深层次的问题是在于内存泄露。
3.什么是内存泄露?
一些对象有自己限制的生命周期,当他们的工作结束时,他们试图去被gc回收,如果当生命周期结束以后内存中仍然握着这个对象的一些应用的时候,就会出现内存泄露。当内存泄露越来越多的时候,就会出现OOM。
例如, 当Activity.onDestroy()被调用的时候,activity对于的布局,相关的bitmap对象都应该被gc回收,如果一个后台线程在运行,并且握着activity的一个引用,那这个引用就没法背回收,最后就会导致OOM。
4.监听内存泄露。
监听内存泄露是一个手动的过程。
下面是几个关键的步骤:
1.学习关于OOM的相关知识。
2.试图去重现这个问题。 你需要去找到出现该问题的手机,你也需要去弄清楚是哪个地方出现这个问题。
3.当出现OOM的时候清空堆内存。
4.使用MAT或者其他工具找到哪些对象需要被回收。
5.计算强引用最短的从该对象到gc根部的路径。 (……)
6. 找出哪些在该path下不该存在的引用,并且修复该内存泄露。
5. 介绍LeakCanary
LeakCanary 是一个开源的java类库,去检测在开发版本中的内存泄露。
让我们在cat中看一个例子:
class Cat {
}
class Box {
Cat hiddenCat;
}
class Docker {
static Box container;
}
// ...
Box box = new Box();
Cat schrodingerCat = new Cat();
box.hiddenCat = schrodingerCat;
Docker.container = box;
你需要创建了一个RefWatcher 实例并且给他赋予一个对象去观察。
// We expect schrodingerCat to be gone soon (or not), let‘s watch it.
refWatcher.watch(schrodingerCat);
当内存被检测出泄露的时候,你会自动获得一个泄露堆栈信息。
* GC ROOT static Docker.container
* references Box.hiddenCat
* leaks Cat instance
我们知道程序员都很忙,所以我们制作了一个和easy的方式去创建,只需要一行代码,LeakCanary 就会自动检测activity的内存泄露。
public class ExampleApplication extends Application {
@Override public void onCreate() {
super.onCreate();
LeakCanary.install(this);
}
}
你会得到一个提醒,和一个漂亮的展示界面
6.结论
启用 LeakCanary以后,我们发现并修正了在我们的应用程序的许多内存泄漏。我们甚至发现在Android SDK中的几个漏洞。现在,我们已经从OOM错误中减少94%的Crash了。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。