Android內(nèi)存泄漏分析及MAT工具使用

1.內(nèi)存泄漏是什么

  • 一句話概括:就是GC垃圾回收機制漏掉的垃圾對象,無法回收
  • 內(nèi)存泄漏過多就會造成內(nèi)存溢出

2.什么是垃圾回收機制?

就是當(dāng)對象不具備任何引用的時候,可被回收

3.GC ROOT Tracing 算法

GC Root Tracing
  • 被GC Root 引用的對象不可被回收
  • 沒有被GC Root Obj所持有的對象可以被回收

4.可以作為GC Root引用的點是(不被回收):

  • java stack中引用的對象
  • 方法區(qū)中靜態(tài)引用指向的對象
  • 方法去中常量引用指向的對象
  • Native方法中jni引用的對象
  • Thread—活著的線程

5.常見的內(nèi)存泄漏案例:

參考QQ空間Android內(nèi)存泄漏分析心得

  • 1:單例造成的內(nèi)存泄漏

    • 解決方案
      • 將該屬性的引用方式改為弱引用;
      • 如果傳入Context,使用ApplicationContext;
  • 2: InnerClass匿名內(nèi)部類

    • 在Java中,非靜態(tài)內(nèi)部類 和 匿名類 都會潛在的引用它們所屬的外部類,但是,靜態(tài)內(nèi)部類卻不會。如果這個非靜態(tài)內(nèi)部類實例做了一些耗時的操作,就會造成外圍對象不會被回收,從而導(dǎo)致內(nèi)存泄漏。
    • 解決方案
      • 將內(nèi)部類變成靜態(tài)內(nèi)部類;
      • 如果有強引用Activity中的屬性,則將該屬性的引用方式改為弱引用;
      • 在業(yè)務(wù)允許的情況下,當(dāng)Activity執(zhí)行onDestory時,結(jié)束這些耗時任務(wù);
  • 3:Activity Context 的不正確使用

    • 在Android應(yīng)用程序中通常可以使用兩種Context對象:Activity和Application。當(dāng)類或方法需要Context對象的時候常見的做法是使用第一個作為Context參數(shù)。這樣就意味著View對象對整個Activity保持引用,因此也就保持對Activty的所有的引用。
    • 解決方案
      • 使用ApplicationContext代替ActivityContext,因為ApplicationContext會隨著應(yīng)用程序的存在而存在,而不依賴于activity的生命周期;
      • 對Context的引用不要超過它本身的生命周期,慎重的對Context使用“static”關(guān)鍵字。Context里如果有線程,一定要在onDestroy()里及時停掉。
  • 4:Handler引起的內(nèi)存泄漏

    • 當(dāng)Handler中有延遲的的任務(wù)或是等待執(zhí)行的任務(wù)隊列過長,由于消息持有對Handler的引用,而Handler又持有對其外部類的潛在引用,這條引用關(guān)系會一直保持到消息得到處理,而導(dǎo)致了Activity無法被垃圾回收器回收,而導(dǎo)致了內(nèi)存泄露。
    • 解決方案
      • 可以把Handler類放在單獨的類文件中,或者使用靜態(tài)內(nèi)部類便可以避免泄露;
      • 如果想在Handler內(nèi)部去調(diào)用所在的Activity,那么可以在handler內(nèi)部使用弱引用的方式去指向所在Activity.使用Static + WeakReference的方式來達到斷開Handler與Activity之間存在引用關(guān)系的目的。
  • 5:注冊監(jiān)聽器的泄漏

    • 解決方案
      • 使用ApplicationContext代替ActivityContext;
      • 在Activity執(zhí)行onDestory時,調(diào)用反注冊;
  • 6:Cursor,Stream沒有close,View沒有recyle

  • 7:集合中對象沒清理造成的內(nèi)存泄漏

    • 在Activity退出之前,將集合里的東西clear,然后置為null,再退出程序。
  • 8: WebView造成的泄露

    • 當(dāng)我們不要使用WebView對象時,應(yīng)該調(diào)用它的destory()函數(shù)來銷毀它,并釋放其占用的內(nèi)存,否則其占用的內(nèi)存長期也不能被回收,從而造成內(nèi)存泄露。
  • 9:構(gòu)造Adapter時,沒有使用緩存的ConvertView

6.使用AndroidStudio進行內(nèi)存分析

步驟如下:

圖1:


圖1

圖2:


圖2
圖2

7.通過MAT工具進行分析

第一步:如下圖先導(dǎo)出標(biāo)準(zhǔn)的hprof文件。可以生成兩個hprof文件,通過MAT比較分析。


圖1

第二步:打開MAT工具,可以單獨下載這個插件下載

圖2

第三步:導(dǎo)入兩個hprof文件,根據(jù)下圖的步驟進行比較分析


圖3

第四步:按照下圖步驟選擇


圖4

最后:找到未釋放的引用


圖5

參考:
QQ空間Android內(nèi)存泄漏分析心得

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Android 內(nèi)存泄漏總結(jié) 內(nèi)存管理的目的就是讓我們在開發(fā)中怎么有效的避免我們的應(yīng)用出現(xiàn)內(nèi)存泄漏的問題。內(nèi)存泄漏...
    _痞子閱讀 1,652評論 0 8
  • 內(nèi)存管理的目的就是讓我們在開發(fā)中怎么有效的避免我們的應(yīng)用出現(xiàn)內(nèi)存泄漏的問題。內(nèi)存泄漏大家都不陌生了,簡單粗俗的講,...
    宇宙只有巴掌大閱讀 2,399評論 0 12
  • 作者:小強 貝聊移動開發(fā)部 Android工程師 1.Java內(nèi)存分配策略 Java 程序運行時的內(nèi)存分配策略有三...
    貝聊科技閱讀 2,172評論 1 7
  • 章節(jié)一 坐上一輛公交車,發(fā)現(xiàn)車廂空蕩,找個自己喜歡的位置,坐下。 窗外都是熟悉的燈光,熟悉的路,安靜看著,感覺自己...
    筆尖的舞蹈閱讀 184評論 0 0
  • 這兩天一直挺忙的,親子日記也沒時間寫了,晚上補上吧。快要過中秋了,這兩天我都在家做月餅,親戚比較多,晚上都要做到半...
    王鐿皓媽媽閱讀 120評論 0 0