日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeakCanary: 让内存泄露无所遁形

發布時間:2025/3/20 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeakCanary: 让内存泄露无所遁形 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

LeakCanary: 讓內存泄露無所遁形

09 May 2015


本文為LeakCanary: Detect all memory leaks!的翻譯。原文在:?https://corner.squareup.com/2015/05/leak-canary.html

java.lang.OutOfMemoryErrorat android.graphics.Bitmap.nativeCreate(Bitmap.java:-2)at android.graphics.Bitmap.createBitmap(Bitmap.java:689)at com.squareup.ui.SignView.createSignatureBitmap(SignView.java:121)

誰也不會喜歡?OutOfMemoryError

在?Square Register?中, 在簽名頁面,我們把客戶的簽名畫在 bitmap cache 上。 這個 bitmap 的尺寸幾乎和屏幕的尺寸一樣大,在創建這個 bitmap 對象時,經常會引發?OutOfMemoryError,簡稱OOM。

當時,我們嘗試過一些解決方案,但都沒解決問題

  • 使用 Bitmap.Config.ALPHA_8 因為,簽名僅有黑色。

  • 捕捉?OutOfMemoryError, 嘗試 GC 并重試(受?GCUtils?啟發)。

  • 我們沒想過在 Java heap 內存之外創建 bitmap 。苦逼的我們,那會?Fresco?還不存在。

路子走錯了

其實 bitmap 的尺寸不是真正的問題,當內存吃緊的時候,到處都有可能引發 OO。在創建大對象,比如 bitmap 的時候,更有可能發生。OOM 只是一個表象,更深層次的問題可能是:?內存泄露

什么是內存泄露

一些對象有著有限的生命周期。當這些對象所要做的事情完成了,我們希望他們會被回收掉。但是如果有一系列對這個對象的引用,那么在我們期待這個對象生命周期結束的時候被收回的時候,它是不會被回收的。它還會占用內存,這就造成了內存泄露。持續累加,內存很快被耗盡。

比如,當?Activity.onDestroy?被調用之后,activity 以及它涉及到的 view 和相關的 bitmap 都應該被回收。但是,如果有一個后臺線程持有這個 activity 的引用,那么 activity 對應的內存就不能被回收。這最終將會導致內存耗盡,然后因為 OOM 而 crash。

對戰內存泄露

排查內存泄露是一個全手工的過程,這在 Raizlabs 的?Wrangling Dalvik?系列文章中有詳細描述。

以下幾個關鍵步驟:

  • 通過?Bugsnag,?Crashlytics?或者?Developer Console?等統計平臺,了解?OutOfMemoryError情況。

  • 重現問題。為了重現問題,機型非常重要,因為一些問題只在特定的設備上會出現。為了找到特定的機型,你需要想盡一切辦法,你可能需要去買,去借,甚至去偷。 當然,為了確定復現步驟,你需要一遍一遍地去嘗試。一切都是非常原始和粗暴的。

  • 在發生內存泄露的時候,把內存 Dump 出來。具體看這里。

  • 然后,你需要在?MAT?或者?YourKit?之類的內存分析工具中反復查看,找到那些原本該被回收掉的對象。

  • 計算這個對象到 GC roots 的最短強引用路徑。

  • 確定引用路徑中的哪個引用是不該有的,然后修復問題。

  • 很復雜對吧?

    如果有一個類庫能在發生 OOM 之前把這些事情全部都搞定,然后你只要修復這些問題就好了,豈不妙哉!

    LeakCanary

    LeakCanary?是一個檢測內存泄露的開源類庫。你可以在 debug 包種輕松檢測內存泄露。

    先看一個例子:

    class Cat { }class Box {Cat hiddenCat; } class Docker {// 靜態變量,將不會被回收,除非加載 Docker 類的 ClassLoader 被回收。static Box container; }// ...Box box = new Box();// 薛定諤之貓 Cat schrodingerCat = new Cat(); box.hiddenCat = schrodingerCat; Docker.container = box;

    創建一個RefWatcher,監控對象引用情況。

    // 我們期待薛定諤之貓很快就會消失(或者不消失),我們監控一下 refWatcher.watch(schrodingerCat);

    當發現有內存泄露的時候,你會看到一個很漂亮的 leak trace 報告:

    • GC ROOT static Docker.container
    • references Box.hiddenCat
    • leaks Cat instance

    我們知道,你很忙,每天都有一大堆需求。所以我們把這個事情弄得很簡單,你只需要添加一行代碼就行了。然后 LeakCanary 就會自動偵測 activity 的內存泄露了。

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

    然后你會在通知欄看到這樣很漂亮的一個界面:

    結論

    使用 LeakCanary 之后,我們修復了我們 APP 中相當多的內存泄露。我們甚至發現了?Android SDK 中的一些內存泄露問題。

    結果是驚艷的,我們減少了 94% 的由 OOM 導致的 crash。

    如果你也想消滅 OOM crash,那還猶豫什么,趕快使用?LeakCanary

    相關鏈接:

    • LeakCanary 中文使用說明

    • 一個非常簡單的 LeakCanary demo:?https://github.com/liaohuqiu/leakcanary-demo

    • ? ? 本文轉自 一點點征服 ? 博客園博客,原文鏈接:http://www.cnblogs.com/ldq2016/p/6635816.html

    • ,如需轉載請自行聯系原作者

    總結

    以上是生活随笔為你收集整理的LeakCanary: 让内存泄露无所遁形的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。