Android 內存泄漏工具使用分析

最近的一次事件讓我對 Android 開發中內存泄漏重視起來,平時只忙着開發新的功能,往往會忽略掉內存,cpu 等方面的使用情況,然而遇到 內存泄露或者ANR 問題就要徹底解決,由於Android設備規格不一,好一些的設備上不會出現問題,在一些低端的設備上就會出現各種問題,所以平時也要注意內存泄漏和 cpu 使用問題.
同步發不在簡書Android 內存泄漏工具使用分析

內存泄漏(memory leak)

A memory leak is a particular type of unintentional memory consumption by a computer program where the program fails to release memory when no longer needed. This condition is normally the result of a bug in a program that prevents it from freeing up memory that it no longer needs.This term has the potential to be confusing, since memory is not physically lost from the computer. Rather, memory is allocated to a program, and that program subsequently loses the ability to access it due to program logic flaws.

看不懂 pass。。。知道有這麼回事就可以了

初步判斷

現象判斷

從現象入手,如果肉眼能看出頁面卡頓,那肯定是有問題的,首先,嘗試連續多次打開應用,觀察界面卡頓,動畫現象,並截取 log,觀察 log 中的 GC 輸出
日誌,頻繁打印GC日誌,說明系統頻繁觸發GC來釋放內存,初步推斷可能存在內存泄漏,具體使用 DDMS HEAP 工具分析,以下有介紹

內存命令分析

前期可以通過一些 ADB 命令來簡單查看下內存相關信息,做初步判斷,有一次在項目中發現,開啓/關閉某個模塊,觀察內存狀態,竟然差了4M,果斷修復。

查看內存系統信息

    adb shell cat proc/meminfo

    ➜  ~ adb shell cat proc/meminfo
    MemTotal:        2052484 kB
    MemFree:         1450748 kB
    Buffers:           23212 kB
    Cached:           342548 kB
    SwapCached:            0 kB
    Active:           338056 kB
    Inactive:         203652 kB
    Active(anon):     175960 kB
    Inactive(anon):     6912 kB
    Active(file):     162096 kB
    Inactive(file):   196740 kB
    ..

查看某一應用佔用內存

    adb shell dumpsys meminfo + packageName
    e.g: adb shell dumpsys meminfo com.dangbeimarket

    ➜  ~ adb shell dumpsys meminfo com.whiskeyfei.tab
    Applications Memory Usage (kB):
    Uptime: 16199425 Realtime: 16199425

    ** MEMINFO in pid 14522 [com.whiskeyfei.tab] **
                       Pss  Private  Private  Swapped     Heap     Heap     Heap
                     Total    Dirty    Clean    Dirty     Size    Alloc     Free
                    ------   ------   ------   ------   ------   ------   ------
      Native Heap     3474     3356        0        0    15475    15475    13196
      Dalvik Heap     2861     2788        0        0     3156     2561      595
     Dalvik Other      340      328        0        0
            Stack      104      104        0        0
        Other dev        5        0        4        0
         .so mmap     1162      144       48        0
        .apk mmap      220        0       16        0
        .ttf mmap      126        0       16        0
        .dex mmap     2648        0     2644        0
        code mmap     1220        0       88        0
       image mmap     1051      508        8        0
       Other mmap       23        4        0        0
          Unknown       89       88        0        0
            TOTAL    13323     7320     2824        0    18631    18036    13791        

名詞解釋

  • Native Heap: C++層內存分配。
  • Dalvik Heap: Java層內存分配。
  • Ashmem : 匿名共享內存。
  • Stack: 棧區分配的內存。
  • so mmap: C庫代碼佔用。
  • jar mmap : Java文件佔用。
  • apk mmap: apk代碼佔用。
  • ttf mmap: ttf文件佔用。
  • dex mmap: dex文件代碼佔用的內存。
  • Other mmap: 其他文件佔用的內存

我們要關注 Dalvik Heap 和 Native Heap 佔用內存,在使用應用過程中實時查看內存信息狀態,來初步判斷是否內存使用不當。

DDMS HEAP 工具

Android DDMS 內存監測工具 Heap,可以檢測一個進程的內存變化,根據這個數值變化可以測試應用是否存在泄漏。
用過debug肯定會用 Heap 了,連接設備啓動 app,點 debug 右邊的按鈕即可(Update Heap 鼠標放上去能看到)

DDMS 調試

開始GC,然後就操作 app 觀察,Heap視圖中部有一個data object,即數據對象,也就是我們的程序中對象
正常情況下 Total Size 值都會穩定在一個範圍內,反之如果則 data object 的 Total Size 值在每次GC後不會有明顯的回落
隨着操作次數的增多 Total Size 的值會越來越大,就證明可能存在內存泄漏,然後通過其他工具來找出泄漏的地方;

MAT( Memory Analyzer Tool )

定位問題

通過 MAT 分析分析內存中佔用比較大的對象

MAT 是一個內存分析工具,在使用 DEAP 初步判斷頁面存在內存泄露後,使用 MAT 具體分析出哪寫對象沒有釋放,導致了內存沒有釋放,關於MAT工具安裝,請自行 Google,操作 app,例如:進入某個頁面,退出,點擊 Dump Hprof file 按鈕,等一會會打開MAT視圖,沒有安裝會生成一個文件;

先觀察“Leak suspects”,找出比較大的問題,通過 Dominator Tree 來查看 heap 中比較大的對象,也可以通過 Histogram 查找引用鏈;
Histogram 顯示內存中每個對象的數量大小等信息,可以通過關鍵字來過濾

例如:搜索 com.main.*;這樣就能查找出這些包下面類引用情況,自行右鍵獲得信息,通過提示找出有問題的類或對象,這樣就可以找出內存佔用多或者泄露的問題了;

本例子中查看 Dominator Tree -> 右鍵某一條 -> Path to GC Roots -> exclude weak references

Shallow Heap:對象本身的大小
Retained Heap:對象本身以及它持有的對象的內存總和

驗證

通過查看 Histogram 內存中的類以及實例個數

安裝地址

MAT分析工具

總結

總結了一些常用的工具,用來分析內存問題,以下是注意的步驟

  • 使用 ADB 命令初步分析內存
  • 操作應用觀察 HEAP update 查看當前內存變化,判斷是否存在內存泄露
  • 使用 MAT 來確定哪些代碼引起了內存

如何避免


  • 嚴格遵守生命週期,創建時創建,銷燬時記得回收
  • Bitmip 和 Drawable 記得手動回收
  • 靜態對象引用 Context,導致對象無法釋放,從而導致 Activity 無法釋放
  • 自定義靜態 Handler,Runnable和 Handler 回收
  • 使用 Application Context,少使用 Activity Context

參考文章

隨時記錄..歡迎補充
發佈了18 篇原創文章 · 獲贊 32 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章