Android內存優化工具:內存修改器安卓

整理下Android內存優化常用的幾種工具,top命令、adb shell dumpsys meminfo、Memory Profiler、LeakCanary、MAT

1. top

top命令是Linux下常用的性能分析工具,能夠實時顯示系統中各個進程的資源佔用狀況。

查看top命令的用法

$ adb shell top --help
usage: top [-Hbq] [-k FIELD,] [-o FIELD,] [-s SORT] [-n NUMBER] [-m LINES] [-d SECONDS] [-p PID,] [-u USER,]

Show process activity in real time.

-H  Show threads
-k  Fallback sort FIELDS (default -S,-%CPU,-ETIME,-PID)
-o  Show FIELDS (def PID,USER,PR,NI,VIRT,RES,SHR,S,%CPU,%MEM,TIME+,CMDLINE)
-O  Add FIELDS (replacing PR,NI,VIRT,RES,SHR,S from default)
-s  Sort by field number (1-X, default 9)
-b  Batch mode (no tty)
-d  Delay SECONDS between each cycle (default 3)
-m  Maximum number of tasks to show
-n  Exit after NUMBER iterations
-p  Show these PIDs
-u  Show these USERs
-q  Quiet (no header lines)

Cursor LEFT/RIGHT to change sort, UP/DOWN move list, space to force
update, R to reverse sort, Q to exit.
複製代碼

使用top命令顯示一次進程信息,以便講解進程信息中各字段的含義

^[[41;173RTasks: 754 total,   1 running, 753 sleeping,   0 stopped,   0 zombie
  Mem:      5.5G total,      5.4G used,      165M free,       76M buffers
 Swap:      2.5G total,      789M used,      1.7G free,      2.4G cached
800%cpu 100%user   3%nice  54%sys 641%idle   0%iow   3%irq   0%sirq   0%host
  PID USER         PR  NI VIRT  RES  SHR S[%CPU] %MEM     TIME+ ARGS
15962 u0_a894      10 -10 6.6G 187M  76M S 75.6   3.2   8:16.55 asia.bluepay.cl+
  785 system       -2  -8 325M  13M 7.6M S 29.7   0.2  84:03.91 surfaceflinger
25255 shell        20   0  35M 2.7M 1.6M R 21.6   0.0   0:00.16 top -n 1
  739 system       -3  -8 177M 3.6M 2.2M S 10.8   0.0  16:00.36 android.hardwar+
16154 u0_i9086     10 -10 1.3G  40M  19M S  5.4   0.6   0:46.18 com.google.andr+
13912 u0_a87       20   0  17G 197M  86M S  5.4   3.4  23:56.88 com.tencent.mm
24789 root         RT  -2    0    0    0 D  2.7   0.0   0:01.36 [mdss_fb0]
24704 root         20   0    0    0    0 S  2.7   0.0   0:01.20 [kworker/u16:12]
20096 u0_a94       30  10 6.1G 137M  53M S  2.7   2.3   0:31.45 com.xiaomi.mark+
 2272 system       18  -2 8.7G 407M 267M S  2.7   7.1 191:11.32 system_server
  744 system       RT   0 1.3G 1.6M 1.4M S  2.7   0.0  72:22.41 android.hardwar+
  442 root         RT   0    0    0    0 S  2.7   0.0   5:59.68 [cfinteractive]
  291 root         -3   0    0    0    0 S  2.7   0.0   5:00.17 [kgsl_worker_th+
   10 root         20   0    0    0    0 S  2.7   0.0   1:55.84 [rcuop/0]
    7 root         20   0    0    0    0 S  2.7   0.0   2:46.82 [rcu_preempt]
25186 shell        20   0  34M 1.9M 1.4M S  0.0   0.0   0:00.71 logcat -v long +
25181 root         20   0    0    0    0 S  0.0   0.0   0:00.00 [kworker/2:3]
25137 root         20   0    0    0    0 S  0.0   0.0   0:00.00 [kworker/1:3]
25118 system       20   0 5.2G  83M  54M S  0.0   1.4   0:01.05 com.android.set+
24946 u0_a57       20   0 5.1G  60M  37M S  0.0   1.0   0:00.82 com.xiaomi.acco+
複製代碼

第 1 行:進程信息

  • 總共(total):754個
  • 運行中(running)狀態:1個
  • 休眠(sleeping)狀態:753個
  • 停止(stopped)狀態:0個
  • 殭屍(zombie)狀態:0個

第 2 行:內存信息

  • 5.5G total:物理內存總量
  • 5.4G used:使用中的內存量
  • 165M free:空閑內存量
  • 76M buffers: 緩存的內存量

第 3 行:Swap分區信息

  • 2.5G total:交換區總量
  • 789M used:使用的交換區大小
  • 1.7G free:空閑交換區大小
  • 2.4G cached:緩衝的交換區大小

內存監控時,可以監控swap交換分區的used,如果這個數值在不斷的變化,說明內核在不斷進行內存和swap的數據交換,這是內存不夠用了。

第 4 行:CPU信息

  • 800%cpu:8核cpu
  • 100%user:用戶進程使用CPU佔比
  • 3%nice:優先值為負的進程佔比
  • 54%sys:內核進程使用CPU佔比
  • 641%idle:除IO等待時間以外的其它等待時間佔比
  • 0%iow:IO等待時間佔比
  • 3%irq:硬中斷時間佔比
  • 0%sirq:軟中斷時間佔比

第 5 行及以下:各進程的狀態監控

  • PID:進程id
  • USER:進程所屬用戶
  • PR:進程優先級
  • NI:nice值,負值表示高優先級,正值表示低優先級
  • VIRT:進程使用的虛擬內存總量,VIRT=SWAP+RES
  • RES:進程使用的、未被換出的物理內存大小,RES=CODE+DATA
  • SHR:共享內存大小
  • S:進程狀態
  • %CPU:上次更新到現在的CPU佔用時間比
  • %MEM:使用物理內存佔比
  • TIME+:進程時間的CPU時間總計,單位1/100秒
  • ARGS:進程名

2. dumpsys meminfo

首先了解下Android中最重要的四大內存指標的概念

指標全稱含義等價
USSUnique Set Size獨佔物理內存進程獨佔的內存
PSSProportional Set Size實際使用物理內存PSS = USS + 按比例包含共享庫內存
RSSResident Set Size實際使用物理內存RSS = USS + 包含共享庫內存
VSSVirtual Set Size虛擬耗用內存VSS = 進程佔用內存(包括虛擬耗用) + 共享庫(包括比例分配部分)

我們主要使用USS和PSS來衡量進程的內存使用情況

dumpsys meminfo命令展示的是系統整體內存情況,內存項按進程進行分類

$ adb shell dumpsys meminfo
Applications Memory Usage (in Kilobytes):
Uptime: 168829244 Realtime: 1465769995

// 根據進程PSS佔用值從大到小排序
Total PSS by process:
    272,029K: system (pid 2272)
    234,043K: com.tencent.mm (pid 13912 / activities)
    185,914K: com.android.systemui (pid 13606)
    107,294K: com.tencent.mm:appbrand0 (pid 5563)
    101,526K: com.tencent.mm:toolsmp (pid 9287)
     96,645K: com.miui.home (pid 15116 / activities)
    ...

// 以oom來劃分,會詳細列舉所有的類別的進程
Total PSS by OOM adjustment:
    411,619K: Native
         62,553K: android.hardware.camera.provider@2.4-service (pid 730)
         21,630K: logd (pid 579)
         16,179K: surfaceflinger (pid 785)
         ...
    272,029K: System
        272,029K: system (pid 2272)
    361,942K: Persistent
        185,914K: com.android.systemui (pid 13606)
         37,917K: com.android.phone (pid 2836)
         23,510K: com.miui.contentcatcher (pid 3717)
         ...
     36,142K: Persistent Service
         36,142K: com.android.bluetooth (pid 26472)
    101,198K: Foreground
         72,743K: com.miui.securitycenter.remote (pid 4125)
         28,455K: com.android.settings (pid 30919 / activities)
    338,088K: Visible
         96,645K: com.miui.home (pid 15116 / activities)
         46,939K: com.miui.personalassistant (pid 31043)
         36,491K: com.xiaomi.xmsf (pid 4197)
         ...
     47,703K: Perceptible
         17,826K: com.xiaomi.metoknlp (pid 4477)
         10,748K: com.lbe.security.miui (pid 5097)
         10,528K: com.xiaomi.location.fused (pid 4563)
          8,601K: com.miui.mishare.connectivity (pid 4227)
     13,088K: Perceptible Low
         13,088K: com.miui.analytics (pid 19306)
    234,043K: Backup
        234,043K: com.tencent.mm (pid 13912 / activities)
     22,028K: A Services
         22,028K: com.miui.powerkeeper (pid 29762)
    198,787K: Previous
         33,375K: com.android.quicksearchbox (pid 31023)
         23,278K: com.google.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0 (pid 16154)
    171,434K: B Services
         45,962K: com.tencent.mm:push (pid 14095)
         31,514K: com.tencent.mobileqq:MSF (pid 12051)
         22,691K: com.xiaomi.mi_connect_service (pid 22821)
         ...
    538,062K: Cached
        107,294K: com.tencent.mm:appbrand0 (pid 5563)
        101,526K: com.tencent.mm:toolsmp (pid 9287)
         72,112K: com.tencent.mm:tools (pid 9187)
        ...

// 按內存的類別來進行劃分
Total PSS by category:
    692,040K: Native
    328,722K: Dalvik
    199,826K: .art mmap
    129,981K: .oat mmap
    126,624K: .dex mmap
    124,509K: Unknown
     92,666K: .so mmap
     68,189K: Dalvik Other
     53,491K: .apk mmap
     44,104K: Gfx dev
     28,099K: Other mmap
     24,960K: .jar mmap
      7,956K: Ashmem
      3,700K: Stack
      3,368K: Other dev
        450K: .ttf mmap
          4K: Cursor
          0K: EGL mtrack
          0K: GL mtrack
          0K: Other mtrack

// 手機整體內存使用情況
Total RAM: 5,862,068K (status normal)
 Free RAM: 3,794,646K (  538,062K cached pss + 3,189,244K cached kernel +         0K cached ion +    67,340K free)
 Used RAM: 2,657,473K (2,208,101K used pss +   449,372K kernel)
 Lost RAM:   487,987K
     ZRAM:   219,996K physical used for   826,852K in swap (2,621,436K total swap)
   Tuning: 256 (large 512), oom   322,560K, restore limit   107,520K (high-end-gfx)
複製代碼

查看單個進程的內存信息,命令如下

adb shell dumpsys meminfo [pid | packageName]
複製代碼

我們查看下微信的內存信息

$ adb shell dumpsys meminfo com.tencent.mm
Applications Memory Usage (in Kilobytes):
Uptime: 169473031 Realtime: 1466413783

** MEMINFO in pid 13912 [com.tencent.mm] **
                   Pss  Private  Private  SwapPss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap    51987    51924        0    61931   159044   139335    19708
  Dalvik Heap    74302    74272        8     2633   209170   184594    24576
 Dalvik Other    10136    10136        0      290
        Stack       84       84        0        8
       Ashmem        2        0        0        0
      Gfx dev     8808     8808        0        0
    Other dev      156        0      156        0
     .so mmap     9984      984     7436     8493
    .jar mmap     1428        0      560        0
    .apk mmap     2942        0     1008        0
    .ttf mmap     1221        0     1064        0
    .dex mmap    31302       44    30004      528
    .oat mmap     2688        0      232        0
    .art mmap     2792     2352       40     3334
   Other mmap     6932     2752      632        0
      Unknown     4247     4232        4     7493
        TOTAL   293721   155588    41144    84710   368214   323929    44284

 App Summary
                       Pss(KB)
                        ------
           Java Heap:    76664
         Native Heap:    51924
                Code:    41332
               Stack:       84
            Graphics:     8808
       Private Other:    17920
              System:    96989

               TOTAL:   293721       TOTAL SWAP PSS:    84710

 Objects
               Views:      623         ViewRootImpl:        1
         AppContexts:        9           Activities:        1
              Assets:       12        AssetManagers:        0
       Local Binders:      198        Proxy Binders:      183
       Parcel memory:       46         Parcel count:      185
    Death Recipients:      125      OpenSSL Sockets:        1
            WebViews:        0

 SQL
         MEMORY_USED:      156
  PAGECACHE_OVERFLOW:       13          MALLOC_SIZE:      117

 DATABASES
      pgsz     dbsz   Lookaside(b)          cache  Dbname
         4       28             46       721/26/4  /data/user/0/com.tencent.mm/databases/Scheduler.db

 Asset Allocations
    : 409K
    : 12K
    : 1031K
複製代碼
  1. App Summary各項指標解讀如下,通常我們需要重點關注Java Heap和Native Heap的大小,如果持續上升,有可能存在內存泄露。
屬性內存組成
Java HeapDalvik Heap的Private Dirty + .art mmap的Private Dirty&Private Clean
Native HeapNative Heap的Private Dirty
Code.so mmap + .jar mmap + .apk mmap + .ttf.mmap + .dex.mmap + .oat mmap的Private Dirty&Private Clean
StackStack的Private Dirty
GraphicsGfx dev + EGL mtrack + GL mtrack的Private Dirty&Private Clean
  1. Objects中Views、Activities、AppContexts的異常可以判斷有內存泄露,比如剛退出應用,查看Activites是否為0,如果不為0,則有Activity沒有銷毀。

3. Memory Profiler

Memory Profiler是 Android Profiler 中的一個組件,實時圖表展示應用內存使用量,識別內存泄露和抖動,提供捕獲堆轉儲,強制GC以及跟蹤內存分配的能力。

Android Profiler官方文檔

4. Leak Canary

非常好用的內存泄露檢測工具,對於Activity/Fragment的內存泄露檢測非常方便。

Square公司開源 官網地址,原理後面單獨分析。

5. MAT

MAT是Memory Analyzer tool的縮寫,是一個非常全面的分析工具,使用相對複雜點。 關於安裝和配置有很多很好的文章結束,這裡就不單獨講了,後面分析具體案例。

Android 內存優化篇 – 使用profile 和 MAT 工具進行內存泄漏檢測

使用Android Studio和MAT進行內存泄漏分析

內存問題高效分析方法

  1. 接入LeakCanary,監控所有Activity和Fragment的釋放,App所有功能跑一遍,觀察是否有抓到內存泄露的地方,分析引用鏈找到並解決問題,如此反覆,直到LeakCanary檢查不到內存泄露。
  2. adb shell dumpsys meminfo命令查看退出界面後Objects的Views和Activities數目,特別是退出App後數目為否為0。
  3. 打開Android Studio Memory Profiler,反覆打開關閉頁面多次,點擊GC,如果內存沒有恢復到之前的數值,則可能發生了內存泄露。再點擊Profiler的垃圾桶圖標旁的heap dump按鈕查看當面內存堆棧情況,按包名找到當前測試的Activity,如果存在多份實例,則很可能發生了內存泄露。
  4. 對於可疑的頁面dump出內存快照文件,轉換後用MAT打開,針對性的分析。
  5. 觀察Memory Profiler每個頁面打開時的內存波峰和抖動情況,針對性分析。
  6. 開發者選項中打開“不保留後台活動”,App運行一段時間後退到後台,觸發GC,dump內存快照。MAT分析靜態內容是否有可以優化的地方,比如圖片緩存、單例、內存緩存等。

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/219104.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-09 10:08
下一篇 2024-12-09 10:08

相關推薦

發表回復

登錄後才能評論