天天看点

LeakCanary: 让内存泄露无所遁形

09 May 2015

当时,我们尝试过一些解决方案,但都没解决问题

使用 Bitmap.Config.ALPHA_8 因为,签名仅有黑色。

其实 bitmap 的尺寸不是真正的问题,当内存吃紧的时候,到处都有可能引发 OO。在创建大对象,比如 bitmap 的时候,更有可能发生。OOM 只是一个表象,更深层次的问题可能是: 内存泄露。

一些对象有着有限的生命周期。当这些对象所要做的事情完成了,我们希望他们会被回收掉。但是如果有一系列对这个对象的引用,那么在我们期待这个对象生命周期结束的时候被收回的时候,它是不会被回收的。它还会占用内存,这就造成了内存泄露。持续累加,内存很快被耗尽。

比如,当 <code>Activity.onDestroy</code> 被调用之后,activity 以及它涉及到的 view 和相关的 bitmap 都应该被回收。但是,如果有一个后台线程持有这个 activity 的引用,那么 activity 对应的内存就不能被回收。这最终将会导致内存耗尽,然后因为 OOM 而 crash。

以下几个关键步骤:

重现问题。为了重现问题,机型非常重要,因为一些问题只在特定的设备上会出现。为了找到特定的机型,你需要想尽一切办法,你可能需要去买,去借,甚至去偷。 当然,为了确定复现步骤,你需要一遍一遍地去尝试。一切都是非常原始和粗暴的。

计算这个对象到 GC roots 的最短强引用路径。

确定引用路径中的哪个引用是不该有的,然后修复问题。

很复杂对吧?

如果有一个类库能在发生 OOM 之前把这些事情全部都搞定,然后你只要修复这些问题就好了,岂不妙哉!

先看一个例子:

创建一个<code>RefWatcher</code>,监控对象引用情况。

当发现有内存泄露的时候,你会看到一个很漂亮的 leak trace 报告:

GC ROOT static Docker.container

references Box.hiddenCat

leaks Cat instance

我们知道,你很忙,每天都有一大堆需求。所以我们把这个事情弄得很简单,你只需要添加一行代码就行了。然后 LeakCanary 就会自动侦测 activity 的内存泄露了。

然后你会在通知栏看到这样很漂亮的一个界面:

结果是惊艳的,我们减少了 94% 的由 OOM 导致的 crash。

相关链接:

<a href="https://www.liaohuqiu.net/cn/posts/leak-canary-read-me/">LeakCanary 中文使用说明</a>

    本文转自 一点点征服   博客园博客,原文链接:http://www.cnblogs.com/ldq2016/p/6635816.html

,如需转载请自行联系原作者