今天刷微博,發(fā)現各位Android開源大神都在轉發(fā)一條關于Square開源的自動探測內存泄露庫LeakCanary的信息。

自動探測內存泄露,這也太牛逼了吧!進入@扔物線110 分享的鏈接了解了下,對原文作簡單翻譯:(翻譯水平有限,湊合看吧-_-)
原文:https://corner.squareup.com/2015/05/leak-canary.html
LeakCanary開源庫地址:https://github.com/square/leakcanary
LeakCanary:探測所有內存泄露!
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)
沒有人喜歡OOM錯誤的出現
在Square Register應用中,我們實現在一個位圖緩存bitmap cache中讓客戶簽名draw the customer's signature,這個bitmap占據設備屏幕的大小,當我們創(chuàng)建一個bitmap時,會出現一個很嚴重的OOM問題。

我們試過幾種方法,但是沒有一種可以解決這個問題:
- 使用 Bitmap.Config.ALPHA_8 (一種不需要顏色的簽名)
- 捕捉OOM錯誤,觸發(fā)GC,并重試幾次(由GCUtils想起的)
- 我們并不打算脫離Java heap分配位圖內存。對于我們幸運的是,開源圖片處理庫Fresco至今不存在這個問題
其實,我們一直以一個錯誤的方式思考這個問題了
這個bitmap的尺寸不是問題所在。當內存幾乎滿時,OOM隨時會發(fā)生。OOM常會發(fā)生在你創(chuàng)建大對象如bitmap的地方。OOM出現是一個更深層次問題內存泄露的征兆。
什么是內存泄露(memory leak)?
一些對象有有限的使用期,當它們的工作完成后,它們預期會被當作內存垃圾回收。如果一個持有對象的引用鏈結束了它的預期壽命,這將會產生一個內存泄露。隨著泄露的積累,應用程序將會耗盡內存。
例如,Activity的onDestroy()被調用后,這個Activity的視圖層次和相關的位圖都應該進行垃圾回收。而如果一個線程在后臺運行這個Activity的引用,那么相應的內存將不能被回收,這最終就導致了OutOfMemoryError的出現。
搜尋內存泄露(memory leaks)
搜尋內存泄露是一個手動過程,在Raizlabs上的Wrangling Dalvik系列文章中得到很好的描述。
這里是關鍵步驟:
- 通過Bugsnag, Crashlytics或Google的Developer Console了解OOM問題;
- 嘗試重現問題。你需要想盡辦法找到出現內存泄露的設備(You might need to buy, borrow, or steal the specific device that suffered the crash.) 不是所有設備都有內存泄露問題?;蛘吣阋残枰约褐谱鲀却嫘孤丁?/li>
- 當OOM出現時進行堆轉儲(dump the heap);
- 使用MAT或YourKit內存檢測工具檢測內存的變化,并找出哪個對象應該被垃圾回收;
- 從那個對象到GC roots推斷最短的強引用路徑;
- 在路徑中找出不存在的引用,并修復memory leak;
- 要是有一個庫能夠在程序出現OOM前做這些檢測,讓你專注于解決內存泄露,那該多好呀?
(注:好,LeakCanary正能做到!)
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;
創(chuàng)建一個Refwatcher的實例并傳入一個Cat對象:
// 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
我們知道你正忙著寫功能,所以我們使LeakCanary更容易地設置。只用一行代碼,LeakCanary就可以自動檢測活躍的泄露。
public class ExampleApplication extends Application {
@Override public void onCreate() {
super.onCreate();
LeakCanary.install(this);
}
}
當內存不足時,會有一個通知和良好的展示界面:

總結:
使用LeakCanary后,我們在我們的app中發(fā)現并修復了很多內存泄露問題,我們甚至發(fā)現了一些Android SDK自身的內存泄露。
有了LeakCanary的結果是驚人的,我們現在減少了94%的OOM錯誤。
如果你想消除OOM引起的崩潰,[現在就安裝LeakCanary吧](If you want to eliminate OOM crashes, install LeakCanary now!)!
注:搜索資料時,發(fā)現Hacker News和reddit上開發(fā)者對LeakCanary滿滿的贊言,Square(電子現金支付公司)確實是非常棒的一家公司,Github上有很多優(yōu)秀的開源項目,如okhttp, dagger, picasso, otto, retrofit等。技術型驅動的公司就是贊!
第一次翻譯才知道自己的英語有多渣o(╯□╰)o, 做技術的,英語水平低確實是一個瓶頸,好好加油吧!
From: 內存泄露自動探測神器——LeakCanary