【Android記憶體流失檢測】LeakCanary使用總結

來源:互聯網
上載者:User

標籤:分析檔案   工具   其他   xtend   java   工作   strong   地址   二次   

一、什麼是LeakCanary?

LeakCanary就是用來檢測Android端記憶體流失的一個工具。能夠檢測Activity的泄漏

 

什麼是記憶體流失?

Java 對象有時也會”長死不死“,GC 拿它沒有辦法,這種情況就是記憶體流失。造成這種情況的原因是:Java 對象被另一個生命週期更長對象持有,具有 可達性 ,這並不是我們想要的。

來自 <http://www.jianshu.com/p/3f1a1cc1e964>

 

記憶體流失的危害?

記憶體流失最終將導致記憶體溢出,也就是OOM,並且OOM發生在某一處,並不代表問題就是出在那裡的,只是剛好有一塊記憶體申請,此時記憶體又不夠了才導致的,比較容易出現在申請比較大的記憶體的情況下。但是把這塊申請的記憶體降低並不能從根本上解決問題。

 

這裡有一個問題就是:記憶體的分配方式,分配位置,比如BitMap的分配,以及其他對象的分配?以及Activity對對象的持有,這個概念還不是很清晰。

 

github上的地址:https://github.com/square/leakcanary

 

一個原理的介紹內容在這裡:

https://www.liaohuqiu.net/cn/posts/leak-canary/

https://www.liaohuqiu.net/cn/posts/leak-canary-read-me/

 

 

二、LeakCanary的工作原理是什嗎?

 

這三個都有講解,並且還有直接通過源碼來進行講解的,後面可以針對這塊,針對源碼專門研究一下。

http://www.jianshu.com/p/a8900eb3de12

 

http://www.jianshu.com/p/5ee6b471970e

http://www.jianshu.com/p/3f1a1cc1e964

 

 

工作原理是:

LeakCanary會開啟一個Service,這個Service能夠在一個Activity被OnDestory之後,檢測是否真的還有這個對象,如果還有,會嘗試進行二次確認,如果這個對象還是沒有被釋放掉,則會擷取當時的記憶體狀態,產生一個heap的狀態檔案,然後分析檔案,計算這個對象的GC ROOT的最短強引用路徑,確定是否泄漏,如果有泄漏,Leak的APP就會有一條通知欄訊息出現

 

 

檢測流程圖如下:

 

 

 

三、如何使用

 

1、在build.gradle中引入:

 

 debugCompile ‘com.squareup.leakcanary:leakcanary-android:1.3.1‘ // or 1.4-beta1
    releaseCompile ‘com.squareup.leakcanary:leakcanary-android-no-op:1.3.1‘ // or 1.4-beta1
    testCompile ‘com.squareup.leakcanary:leakcanary-android-no-op:1.3.1‘ // or 1.4-beta1

 

 

或者,現在最新的1.5.1的也可以直接用:

dependencies{

compile‘com.squareup.leakcanary:leakcanary-android:1.5.1‘

}

 

 

2、同時,在Application的方法,在OnCreate中添加install

 

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

3、在添加之後,直接打出來應用的包,裝上之後,會看到有一個附屬應用出來,名字叫做Leaks

 

4、直接操作APP,如果發現有記憶體流失,則這個過程中會有通知欄提示,點擊查看即可,可以將泄漏的資訊分享,也可以將當時的heap dump的資訊分享出來(但有可能這個heap dump不一定存在)

 

以檢測出來的一個圖為例:

 

 

LeakCanary的記憶體泄露提示一般會包含三個部分:

第一部分(LeakSingle類的sInstance變數)引用第二部分(LeakSingle類的mContext變數), 導致第三部分(MainActivity類的執行個體instance)泄露.

 

 

下方是一些更詳細的原理的講解:

1、不同的幾種引用方式:強-軟-弱-虛

2、LeakCanary這裡,有一個原理的講解叫做:

 

 

需要理解為什麼要用WeakReference,因為GC的時候是不會對強引用的做處理,而軟引用的是在記憶體不夠用了才會被回收,而弱引用就是可以隨時回收,所以需要用WeakReference對待檢測的對象進行包裹引用,因為是弱引用的,因此在待檢測對象調用了Destory或者Finish方法之後,被WeakReference引用的對象的生命週期結束,因為這個是弱引用,就會被GC檢測到,這個時候GC會把該對象添加到ReferenceQueue中,如果GC結束該對象還是沒有被加入到ReferenceQueue中,則說明可能存在記憶體流失,其實就是找到所有生命週期結束的對象,過濾掉會被回收的,剩下就是沒有被回收的,然後會做二次GC,之後還是沒有回收,就可以找到當時的記憶體狀態,拿到不同對象的引用情況,得到一個hprof的檔案,之後就能找到最短強引用的路徑。

 

解決記憶體流失,通過以下方式:

然後我們需要解決:如何得到未被回收的對象。ReferenceQueue+WeakReference+手動調用 GC可實現這個需求。

 

  • WeakReference 建立時,傳入一個 ReferenceQueue 對象。當被 WeakReference 引用的對象的生命週期結束,一旦被 GC 檢查到,GC 將會把該對象添加到 ReferenceQueue 中,待ReferenceQueue處理。當 GC 過後對象一直不被加入 ReferenceQueue,它可能存在記憶體流失。

 

獲得未被回收的 Object

  • 找到了未被回收的對象,如何確認是否真的記憶體流失?這裡可以將問題轉換為:未被回收的對象,是否被其他對象引用?找出其最短引用鏈。VMDebug + HAHA 完成需求。
    VM 會有堆內各個對象的引用情況,並能以hprof檔案匯出。HAHA 是一個由 square 開源的 Android 堆分析庫,分析 hprof 檔案產生Snapshot對象。Snapshot用以查詢對象的最短引用鏈。

 

解析hprof

  • 找到最短引用鏈後,定位問題,排查代碼將會事半功倍。

如下泳道圖分析, LeakCanary 各個模組如何配合達到檢測目的。

 

 

來自 <http://www.jianshu.com/p/3f1a1cc1e964>

 

 

【Android記憶體流失檢測】LeakCanary使用總結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.