閱讀452 返回首頁    go 阿裏雲 go 技術社區[雲棲]


LeakCanary內存檢測原理

LeakCanary介紹

LeakCanary內存檢測工具是由squar公司開源的著名項目。此項目主要用於內存檢測。
開源鮮明的目錄結構如下:

leakcanary |
|-leakcanary-analyzer
|-leakcanary-android
|-leakcanary-android-no-op
|-leakcanary-watcher
|-leakcanary-simple

leakcanary-android,leakcanary-android-no-op是針對android的檢查封裝。
leakcanary-analyzer:用於分析dump文件
leakcanary-watcher:用於監控內存泄露
leakcanary-android-no-op:空實現。用於release版本的依賴。

理論上這兩個包完全可以應用到普通的java項目中,可以看出squar的工程師模塊化分的特別清楚。

leakcanary-watcher主要提供抽象,核心的內存檢測,執行流程,leakcanary-android負責具體的周邊業務實現。

leakcanary-analyzer主要用作分析dump文件,由leakcanary-android去調用,結果再展示給開發者。

LeakCanary進程和線程

leakcanary在主進程進行內存檢測,並且隻在主線程空閑的時候執行,在單獨的leakcanary進程進行內存分析。

實現原理

在Android開發中,主要用於檢測Activity,Fragment等組件的內存泄露。對於Activity的內存檢測,主要是檢測當Activity執行了onDestory()之後是否還在內存中,如果一直在內存中,GC無法回收,那麼代表內存泄露了,內存泄露的原因基本上都是有地方強引用了這個Activity對象。

無侵入獲取需要檢測的Activity

通過Application.registerActivityLifecycleCallbacks(),注冊Application.ActivityLifecycleCallbacks回調,之後的所有Activity的生命周期都會回調這個接口,當然包括void onActivityDestroyed(Activity activity)方法。

如何判斷對象泄露

獲取了要檢測的Activity對象後,怎麼樣才能判斷這個對象就泄露了呢?

LeakCanary主要利用了WeakRefrence引用的對象,當GC回收了這個對象後,會被放進RefrecenQueue中。

LeakCanary先主動調用GC,然後檢測這個對象是否在ReferenceQueue中,如果在,說明沒有泄露,如果不在,說明有泄露的嫌疑,此處隻是嫌疑,不一定真的泄露了。

為了方便檢測繼承WeakRefrence實現了KeydWeekRefrence,提供了一個唯一識別的Key,有利於對象檢測,包括後麵的Dump分析。

如何獲取Dump文件

android已經提供好了獲取Dump文件的Api:

android.os.Debug.dumpHprofData("dump文件名稱");

如何分析Dump文件

analyzer借助haha分析Dump文件,計算出泄露對象的最短強引用路徑。

以上就是LeakCanary的原理分析。

下麵是分析源碼過程中的類圖和時序圖(PS:都不標準,隻方便理解用)

LeakCanary類關係圖.png

leakcanary init.png

leakcanary watch.png

最後更新:2017-08-30 17:32:41

  上一篇:go  阿裏雲前端周刊 - 第 22 期
  下一篇:go  8月30日雲棲精選夜讀:Nodejs進階:使用DiffieHellman密鑰交換算法