Android | 內存指標與測量方法 目錄 前置知識 1. 內存指標 2. 內存分析命令 3. 內存分析工具

點贊關注,不再迷路,你的支持對我意義重大!

🔥 Hi,我是醜醜。本文 「Android 路線」| 導讀 —— 從零到無窮大 已收錄,這裏有 Android 進階成長路線筆記 & 博客,歡迎跟着彭醜醜一起成長。(聯繫方式在 GitHub)


目錄


前置知識

這篇文章的內容會涉及以下前置 / 相關知識,貼心的我都幫你準備好了,請享用~


1. 內存指標

在討論具體的內存優化方法之前,我們先來討論內存的指標與分析工具。首先你需要理解這些內存指標

1.1 最大堆內存

爲了避免應用濫用內存,Android 系統會限制應用可以申請的最大堆內存,超過此限制就會拋出 OOM 異常。Android 設備出廠後,最大堆內存就已經確定,相關的配置位於系統根目錄/system/build.prop文件中,我們可以通過命令查看:

命令:
adb shell cat /system/build.prop
------------------------------------------------------------------
輸出:
...
dalvik.vm.heapstartsize=16m           [進程啓動的初始堆內存]
dalvik.vm.heapgrowthlimit=128m        [進程最大堆內存]
dalvik.vm.heapsize=192m               [進程最大堆內存(開啓 largeHeap="true")]
dalvik.vm.heaptargetutilization=0.75
dalvik.vm.heapminfree=512k
dalvik.vm.heapmaxfree=8m
...
虛擬機參數 描述
dalvik.vm.heapstartsize 進程啓動的初始堆內存
dalvik.vm.heapgrowthlimit 進程最大堆內存
dalvik.vm.heapsize 進程最大堆內存(開啓 largeHeap="true")
dalvik.vm.heaptargetutilization
dalvik.vm.heapminfree
dalvik.vm.heapmaxfree

在 App 虛擬機啓動時,會讀取/system/build.prop文件的配置,源碼位於:AndroidRuntime.cpp

->虛擬機啓動
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote) {
    ...
    parseRuntimeOption("dalvik.vm.heapstartsize", heapstartsizeOptsBuf, "-Xms", "4m");
    parseRuntimeOption("dalvik.vm.heapsize", heapsizeOptsBuf, "-Xmx", "16m");
    parseRuntimeOption("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit=");
    parseRuntimeOption("dalvik.vm.heapminfree", heapminfreeOptsBuf, "-XX:HeapMinFree=");
    parseRuntimeOption("dalvik.vm.heapmaxfree", heapmaxfreeOptsBuf, "-XX:HeapMaxFree=");
    parseRuntimeOption("dalvik.vm.heaptargetutilization", heaptargetutilizationOptsBuf, "-XX:HeapTargetUtilization=");
    ...
}

需要注意的是,配置dalvik.vm.heapgrowthlimit限制的僅僅是 Java 堆內存,本地內存時不受其限制的。換句話說,應用可以使用的最大內存其實是可以大於最大堆內存的。

1.2 進程到底佔用了多少內存?

在 Linux 裏,一個進程佔用的內存有四種指標,分別是:

內存指標 全稱 關係
VSS Virtual Set Size 一個進程可訪問的地址空間
RSS Resident Set Size 一個進程實際佔用的內存大小(包含共享庫佔用的內存)
PSS Proportional Set Size 一個進程實際佔用的內存大小(按比例計算共享庫佔用的內存)
USS Unique Set Size 進程獨立佔用的物理內存(不包含共享庫佔用的內存)

一般來說內存佔用大小有如下規律:VSS >= RSS >= PSS >= USS。

  • VSS: 一個進程可訪問的地址空間,其大小還包括分配但未使用的內存,因此對於分析進程佔用內存用處不大;

  • RSS: 一個進程實際佔用的內存大小,RSS 同樣也不太準確,主要是因爲 RSS 還包括該進程使用的共享庫。而一個共享庫是可以被多個進程共享的,以至於所有進程的 RSS 相加會超過物理內存很多;

  • PSS: 一個進程實際佔用的內存大小,相對於 RSS,它是按照比例計算共享庫佔用的內存的。例如一個共享庫被 N 個進程共享,那麼 PSS 只會計算 1/N 共享庫內存。PSS 在有些時候也是有偏差的,例如進程 A 和進程 B 使用同一個共享庫沒並且 B 在 A 之後啓動,那麼在 B 啓動的那一刻,A 的 PSS 會突然斷崖式降低,即時 A 並沒有做任何內存釋放,這會給分析進程內存行爲帶來麻煩。

  • USS: 一個進程佔用的私有內存大小,相對於其它指標,USS 不包含共享庫佔用的內存,只包含進程獨佔的內存部分。如果該進程終止,USS 就是實際被返還給系統的內存大小。

—— 圖片引用自 https://www.cnblogs.com/sunsky303/p/13494977.html —— sunsky303 著


2. 內存分析命令

Applications Memory Usage (in Kilobytes):
Uptime: 11344873 Realtime: 11344873

Total PSS by process:
     85,517K: cn.kidyn.qdmedical160 (pid 4273 / activities)
     67,985K: system (pid 1639)
     60,472K: com.android.systemui (pid 1777 / activities)
     58,943K: org.chromium.webview_shell (pid 3990 / activities)
     29,429K: com.android.launcher3 (pid 2331 / activities)
     24,383K: cn.kidyn.qdmedical160:pushservice (pid 4466)
     21,077K: com.android.inputmethod.latin (pid 1744)
     20,671K: com.android.phone (pid 1878)
     20,603K: zygote (pid 1313)
     14,790K: cn.kidyn.qdmedical160:core (pid 4320)
     14,114K: cn.kidyn.qdmedical160:todaystep (pid 5236)
     11,734K: android.process.acore (pid 2422)
     10,912K: com.android.packageinstaller (pid 3718)
     10,824K: com.android.quicksearchbox (pid 2386 / activities)
      6,597K: logd (pid 1256)
      6,249K: com.android.calendar (pid 5161)
      6,179K: com.android.deskclock (pid 2093)
      6,084K: libweexjsb.so (pid 5286)
      6,080K: libweexjsb.so (pid 4516)
      6,076K: libweexjsb.so (pid 4406)
      6,068K: libweexjsb.so (pid 4399)
      5,361K: com.android.gallery3d (pid 2539)
      5,247K: com.android.providers.calendar (pid 5173)
      3,999K: com.android.printspooler (pid 2285)
      3,848K: com.android.defcontainer (pid 2752)
      3,817K: android.ext.services (pid 2176)
      3,811K: audioserver (pid 1314)
      3,739K: mediaserver (pid 1322)
      3,365K: com.svox.pico (pid 2781)
      3,117K: media.extractor (pid 1321)
      2,591K: media.codec (pid 1319)
      2,533K: cameraserver (pid 1315)
      1,930K: surfaceflinger (pid 1308)
      1,907K: mediadrmserver (pid 1320)
      1,583K: wpa_supplicant (pid 1894)
      1,549K: netd (pid 1323)
      1,446K: vold (pid 1265)
      1,319K: drmserver (pid 1316)
      1,253K: sdcard (pid 1789)
      1,241K: sdcard (pid 1860)
      1,085K: /init (pid 1)
      1,074K: hostapd (pid 1596)
      1,045K: adbd (pid 1342)
        927K: keystore (pid 1318)
        718K: rild (pid 1324)
        698K: fingerprintd (pid 1326)
        681K: installd (pid 1317)
        667K: gatekeeperd (pid 1327)
        635K: lmkd (pid 1306)
        572K: ueventd (pid 930)
        551K: logcat (pid 1312)
        520K: healthd (pid 1303)
        493K: dumpsys (pid 5583)
        483K: dnsmasq (pid 1599)
        482K: servicemanager (pid 1307)
        470K: sh (pid 1311)
        442K: sh (pid 1518)
        435K: perfprofd (pid 1333)
        324K: ipv6proxy (pid 1569)
        277K: debuggerd (pid 1264)
        239K: debuggerd:signaller (pid 1267)

Total PSS by OOM adjustment:
     92,345K: Native
         20,603K: zygote (pid 1313)
          6,597K: logd (pid 1256)
          6,084K: libweexjsb.so (pid 5286)
          6,080K: libweexjsb.so (pid 4516)
          6,076K: libweexjsb.so (pid 4406)
          6,068K: libweexjsb.so (pid 4399)
          3,811K: audioserver (pid 1314)
          3,739K: mediaserver (pid 1322)
          3,117K: media.extractor (pid 1321)
          2,591K: media.codec (pid 1319)
          2,533K: cameraserver (pid 1315)
          1,930K: surfaceflinger (pid 1308)
          1,907K: mediadrmserver (pid 1320)
          1,583K: wpa_supplicant (pid 1894)
          1,549K: netd (pid 1323)
          1,446K: vold (pid 1265)
          1,319K: drmserver (pid 1316)
          1,253K: sdcard (pid 1789)
          1,241K: sdcard (pid 1860)
          1,085K: /init (pid 1)
          1,074K: hostapd (pid 1596)
          1,045K: adbd (pid 1342)
            927K: keystore (pid 1318)
            718K: rild (pid 1324)
            698K: fingerprintd (pid 1326)
            681K: installd (pid 1317)
            667K: gatekeeperd (pid 1327)
            635K: lmkd (pid 1306)
            572K: ueventd (pid 930)
            551K: logcat (pid 1312)
            520K: healthd (pid 1303)
            493K: dumpsys (pid 5583)
            483K: dnsmasq (pid 1599)
            482K: servicemanager (pid 1307)
            470K: sh (pid 1311)
            442K: sh (pid 1518)
            435K: perfprofd (pid 1333)
            324K: ipv6proxy (pid 1569)
            277K: debuggerd (pid 1264)
            239K: debuggerd:signaller (pid 1267)
     67,985K: System
         67,985K: system (pid 1639)
     81,143K: Persistent
         60,472K: com.android.systemui (pid 1777 / activities)
         20,671K: com.android.phone (pid 1878)
     29,429K: Foreground
         29,429K: com.android.launcher3 (pid 2331 / activities)
     39,684K: Visible
         21,077K: com.android.inputmethod.latin (pid 1744)
         14,790K: cn.kidyn.qdmedical160:core (pid 4320)
          3,817K: android.ext.services (pid 2176)
     14,114K: A Services
         14,114K: cn.kidyn.qdmedical160:todaystep (pid 5236)
     90,764K: Previous
         85,517K: cn.kidyn.qdmedical160 (pid 4273 / activities)
          5,247K: com.android.providers.calendar (pid 5173)
     24,383K: B Services
         24,383K: cn.kidyn.qdmedical160:pushservice (pid 4466)
    121,414K: Cached
         58,943K: org.chromium.webview_shell (pid 3990 / activities)
         11,734K: android.process.acore (pid 2422)
         10,912K: com.android.packageinstaller (pid 3718)
         10,824K: com.android.quicksearchbox (pid 2386 / activities)
          6,249K: com.android.calendar (pid 5161)
          6,179K: com.android.deskclock (pid 2093)
          5,361K: com.android.gallery3d (pid 2539)
          3,999K: com.android.printspooler (pid 2285)
          3,848K: com.android.defcontainer (pid 2752)
          3,365K: com.svox.pico (pid 2781)

Total PSS by category:
    114,379K: Native
    100,052K: Dalvik
     64,802K: .dex mmap
     54,784K: .so mmap
     44,872K: .oat mmap
     41,614K: .apk mmap
     36,631K: Unknown
     32,520K: Ashmem
     30,866K: .art mmap
     14,411K: Other mmap
     14,162K: Dalvik Other
      9,460K: Stack
      2,019K: .ttf mmap
        501K: Other dev
        160K: .jar mmap
         28K: Cursor
          0K: Gfx dev
          0K: EGL mtrack
          0K: GL mtrack
          0K: Other mtrack

Total RAM: 1,550,644K (status normal)
 Free RAM: 1,036,918K (  121,414K cached pss +   499,892K cached kernel +   415,612K free)
 Used RAM:   514,515K (  439,847K used pss +    74,668K kernel)
 Lost RAM:      -789K
   Tuning: 384 (large 384), oom   184,320K, restore limit    61,440K (high-end-gfx)

3. 內存分析工具


參考資料


創作不易,你的「三連」是醜醜最大的動力,我們下次見!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章