1. 程式人生 > >Android實戰——LeakCanary檢測內存泄漏

Android實戰——LeakCanary檢測內存泄漏

man andro 通知欄 配置 溢出 自動 需要 sdn 問題


本篇文章包括以下內容:

  • 前言
  • 內存泄漏的簡介
  • 內存溢出的簡介
  • LeakCanary的配置與使用
  • 結語

內存泄漏對於初學者們可能是一個陌生的詞語,但是卻頻頻發生於自己的軟件上,只不過自己不知道而已。同理,內存溢出也是一個道理。而內存泄漏和內存溢出常常是面試的考題,所以早點掌握是必不可少的

內存泄漏是指:對象在它有限的生命周期結束時,它們將被垃圾回收,如果在回收時,這個對象還被一系列的引用,導致該對象不會被回收,那麽就會導致內存泄漏。隨著泄漏的累積,應用將消耗完內存,應用的流暢性就會大大減弱

常見的內存泄漏有:

  1. 靜態變量引用導致內存泄漏
  2. 屬性動畫未及時關閉導致的內存泄漏

涉及到內存泄漏,當然也逃不過內存溢出的內容

內存溢出是指:程序要求的內存,超出了系統所能分配的範圍,從而發生溢出。Android應用程序的默認最大內存值為16M,如果你使用的內存超過最大值,則會導致應用報錯

常見的內存溢出有:

  1. 圖片過大導致內存溢出

LeakCanary是square公司開發出來的檢測內存泄漏的神器,他可以嵌入到我們的應用中,幫助我們自動檢測內存泄漏

在項目的gradle中添加對LeakCanary的依賴

首先,需要創建一個類繼承自Application,為了讓我們LeakCanary在全局的Activity中能夠起作用

接著,在Manifests文件中指定該Application

最後,就是在Application中直接配置我們的LeakCanary

到此我們的LeakCanary就已經嵌入成功,就剩測試了

我們采用靜態變量的內存泄漏來作為我們的測試結果,創建一個類,該類的作用可以保存一個Activity對象到一個ArrayList中,讓Activity一直存在

做好了內存泄漏類之後,就在我們的主界面中直接使用該類,並將主界面的Activity存放在ArrayList中

這個時候,我們就已經模擬了內存泄漏了,接著,就可以運行程序進行測試了

我們運行程序進入主界面,那麽主界面的Activity就被保存起來了,軍訓心得這個時候是沒什麽事情的,因為主界面的Activity還被引用,並不會發生內存泄漏。接著,我們退出主界面,按道理是:退出主界面Activity,其生命周期就被結束了,該Activity必須被系統回收,但是我們還留了一手,將它保存起來了,那麽等待一段時間後,就會在通知欄收到LeakCanary的通知信息

技術分享圖片

這個時候,內存泄漏報告就出來了,點擊通知信息,進入內存泄漏報告分析

技術分享圖片

結果分析得:

第一部分(ActivityPool類的activities變量)由於第二部分(ArrayList中的某個數組)和第三部分(數組中的某個對象) 導致第四部分(LeakCanaryActivity類的實例instance)泄露

這樣我們就可以很容易的定位到內存泄漏的部分

上面說到為什麽要在關閉Activity時,等待一段時間才會出現內存泄漏報告呢?

原因是:LeakCanary會監聽所有Activity的生命周期,並且在Activity的onDestory函數結束後,將該Activity添加到內存泄漏監控隊列中。接著,在後臺線程中檢測這個引用是否被清除,如果沒有將會發生GC操作(垃圾回收),如果引用仍然沒有清除,將heap內存dump到一個.hprof文件並存放在手機系統裏,應用會開啟另一個進程來分析該.hprof文件,最後導出泄漏引用鏈,傳回應用程序中,通過推送推送出信息

LeakCanary的使用並不難,重要的是如何排除內存泄漏的問題,可能大部分問題還是需要在實戰中才能摸索出來,這裏只是舉一例子,不過通過這篇之後,相信你對內存泄漏和溢出都有一個大概的了解,對待類似面試題應該是沒什麽問題了

Android實戰——LeakCanary檢測內存泄漏