内存管理-31-系统内存统计-6-dumpsys meminfo

 注: 内存芯片通常以1024为进制单位,存储芯片通常以1000为进制单位。

一、dumpsys meminfo命令数据格式

基于Android-14(U)

# dumpsys meminfo
Applications Memory Usage (in Kilobytes):
Uptime: 2802229 Realtime: 2802229

Total RSS by process:
    313,100K: com.sam.systemui (pid 1848 / activities)
    169,676K: zygote64 (pid 789)
     78,672K: surfaceflinger (pid 983)
     23,076K: init (pid 1)
     22,208K: android.hardware.audio.service.mediatek (pid 812)
      9,972K: sh (pid 10262)
      ...

Total RSS by OOM adjustment:
  1,851,392K: Native
        169,676K: zygote64 (pid 789)
         21,144K: adbd (pid 10227)
          6,744K: android.hardware.boot-service (pid 415)
          ...
    478,508K: System
        478,508K: system (pid 1116) //system_server
  5,472,900K: Persistent
      1,011,564K: com.sam.systemui (pid 2700)
        135,884K: com.android.phone (pid 1853)
        ...
    144,808K: Persistent Service
        144,808K: com.android.providers.media.module (pid 2664)
    926,208K: Foreground
        184,780K: com.sam.car.settings (pid 1955 / activities)
        158,308K: com.sam.caraccount (pid 4090)
        ...
  2,230,584K: Visible
        134,912K: com.sam.btphone (pid 5527)
        111,776K: android.ext.services (pid 3481) (user 10)
        ...
  2,248,828K: Perceptible
        298,372K: com.sam.xpime (pid 6680)
        109,052K: com.mediatek.location.mtkgeofence (pid 3072)
        ...
    432,464K: B Services
        150,188K: com.sam.cardiagnosis (pid 6306)
        146,616K: com.sam.autoshow (pid 6268)
  1,985,924K: Cached
        142,932K: com.sam.appstore (pid 3227)
        122,924K: com.android.rkpdapp (pid 4404)
        121,332K: android.process.media (pid 10238)
        ...

Total RSS by category:
  3,211,292K: .so mmap
  2,734,456K: Native
  2,360,968K: .art mmap
  2,219,852K: .jar mmap
  1,278,964K: Dalvik
    897,860K: .apk mmap
    790,088K: Unknown
    785,988K: .oat mmap
    666,164K: GL mtrack
    310,316K: Other mmap
    190,000K: Dalvik Other
    107,376K: .dex mmap
     92,688K: Other dev
     59,080K: Ashmem
     54,824K: Stack
     11,700K: .ttf mmap
          0K: Cursor
          0K: Gfx dev
          0K: EGL mtrack
          0K: Other mtrack

Total PSS by process:
  1,022,509K: com.sam.carspeech (pid 3186)
    302,883K: system (pid 1116) //system_server
     55,368K: surfaceflinger (pid 983)
     16,719K: adbd (pid 10227)
     ...

Total PSS by OOM adjustment:
  1,722,628K: Native
        165,303K: mtkfastavm (pid 2765)
         86,557K: camerahalserver (pid 1208)
         55,368K: surfaceflinger (pid 983)
         ...
    302,883K: System
        302,883K: system (pid 1116) //system_server
  2,538,575K: Persistent
        872,594K: com.sam.instrument (pid 2700)
          6,862K: com.android.se (pid 1819)
          ...
     24,735K: Persistent Service
         24,735K: com.android.providers.media.module (pid 2664)
    480,609K: Foreground
        301,723K: com.sam.car.settings (pid 3164 / activities)
        ...
  1,178,460K: Visible
      1,022,509K: com.sam.carspeech (pid 3186)
      ...
    776,717K: Perceptible
        164,267K: com.sam.xpime (pid 6680)
          8,965K: com.sam.car.ai (pid 3773)
          ...
     85,791K: B Services
         35,394K: com.sam.cardiagnosis (pid 6306)
         ...
    177,923K: Cached
         28,034K: com.sam.appstore (pid 3227)
         ...

Total PSS by category:
  1,876,492K: Native
    790,289K: Dalvik
    670,243K: .apk mmap
    666,164K: GL mtrack
    590,036K: .so mmap
    568,452K: Unknown
    133,191K: Dalvik Other
    126,129K: Other mmap
     90,951K: .art mmap
     89,693K: .jar mmap
     54,220K: Stack
     37,382K: .dex mmap
     20,804K: Ashmem
     15,118K: .oat mmap
     10,031K: .ttf mmap
      6,072K: Other dev
          0K: Cursor
          0K: Gfx dev
          0K: EGL mtrack
          0K: Other mtrack

Total RAM: 11,194,640K (status normal)
 Free RAM: 2,568,179K (  177,923K cached pss + 1,919,984K cached kernel +   470,272K free)
DMA-BUF: 1,063,552K (  321,048K mapped +   742,504K unmapped)
DMA-BUF Heaps:   716,532K
DMA-BUF Heaps pool:         0K
      GPU: 1,027,356K (  361,192K dmabuf +   666,164K private)
 Used RAM: 9,429,898K (6,765,282K used pss + 2,664,616K kernel)
 Lost RAM:   467,185K
     ZRAM:   272,432K physical used for 1,584,128K in swap (6,157,048K total swap)
   Tuning: 256 (large 512), oom   322,560K, restore limit   107,520K (high-end-gfx)

注:"Total PSS by OOM adjustment" 下的 Persistent 类型的app,被kill掉后会自动重启。

还可以 dumpsys meminfo <pid/包名>,例如:

# dumpsys meminfo $$
Applications Memory Usage (in Kilobytes):
Uptime: 7517156 Realtime: 7517156
                   Pss  Private  Private     Swap      Rss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty    Total     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------   ------
  Native Heap      180      180        0        0      180        0        0        0
  Dalvik Heap        0        0        0        0        0        0        0        0
        Stack       48       48        0        0       48
    Other dev        0        0        0        0      352
     .so mmap      123      116        0        0     1948
   Other mmap      155       56        0        0      988
      Unknown      348      348        0        0      348
        TOTAL      854      748        0        0     3864        0        0        0

 App Summary
                       Pss(KB)                        Rss(KB)
                        ------                         ------
           Java Heap:        0                              0
         Native Heap:      180                            180
                Code:      116                           1948
               Stack:       48                             48
            Graphics:        0                              0
       Private Other:      404
              System:      106
             Unknown:                                    1688

           TOTAL PSS:      854            TOTAL RSS:     3864      TOTAL SWAP (KB):        0

 

1. 相关名词介绍

RSS(Resident Set Size)‌:
这是进程当前在物理内存中占用的空间,包括进程本身和所有链接库。RSS是评估进程内存占用的一个重要指标,它直接反映了进程当前实际使用的物理内存量‌。但由于包含了共享库,用处不大。

PSS(Proportional Set Size)‌:
与RSS不同,PSS考虑了共享内存的情况,它计算了每个进程对共享内存的贡献,并通过等比例来分配共享内存的使用量PSS更适合用来比较不同进程的内存使用情况,因为它避免了重复计算共享内存的问题‌。
此数据非常有用,因为系统中所有进程的PSS都相加的话,就刚好反映了系统中的总共被占用的内存量。而当一个进程被销毁之后, 其占用的共享库那部分比例的PSS,将会再次按比例分配给余下使用该库的进程。

USS(Unique Set Size):
是进程独占的物理内存量,不考虑共享库占用的内存。USS可以用来计算某个进程真正独占的内存资源‌。
USS是非常有用的数据,因为它反映了运行一个特定进程真实的边际成本(增量成本)。当一个进程被销毁后,USS是真实返回给系统的内存。当进程中存在一个可疑的内存泄露时,USS是最佳观察数据。

VSS(Virtual Set Size)
虚拟内存占用,包含共享库,以及分配但未使用内存。其大小还包括可能不在RAM中的内存(比如虽然malloc分配了空间,但尚未写入)。VSS 很少被用于判断一个进程的真实内存使用量,用处不大。

二、dumpsys meminfo系统字段说明

1. Total RAM

Total RAM: 13,221,176K (status normal)

Total RAM 的值等同于meminfo 中的 "MemTotal" 字段。表示系统可见物理内存总量,应该是释放给伙伴系统的物理内存页总量(不含被硬件永久保留的部分)。

status normal:AMS/LMKD 评估的内存水位状态(例如 normal/moderate/low/critical),由可用内存与阈值比较得出。


2. Free RAM

Free RAM: 2,717,384K ( 229,812K cached pss + 2,187,228K cached kernel + 300,344K free)

表示可较快回收或立即可用的内存。统计方法(框架层汇总):
cached pss:处于 cached 状态进程的 PSS 总和(可通过杀缓存进程回收)。
cached kernel:内核可回收缓存(page cache/slab 可回收等)。
free:真正空闲页(等价 cat /proc/meminfo 中的 MemFree)。

公式:Free RAM = cached pss + cached kernel + free。


3. DMA-BUF

DMA-BUF: 1,251,000K ( 396,340K mapped + 854,660K unmapped)

(1) 含义:系统中 DMA-BUF 共享缓冲总占用(常见于图形/多媒体零拷贝路径)。

统计:
mapped:当前被映射到某些地址空间(CPU/进程)可访问的 dmabuf。
unmapped:已分配但当前未映射的 dmabuf。

这部分通常属于内核/驱动管理内存,与 GPU、相机、编解码关联很大。

(2) DMA-BUF 这一行是这样来的:

a. DMA-BUF 总量

来源接口:Debug.getDmabufTotalExportedKb()。含义是系统里“所有导出的 dma-buf 总大小”。底层来源是读取 /sys/kernel/dmabuf/buffers ####目录下的统计结果(通过 native 库 dmabufinfo 聚合),不是简单固定单文件值。

b. mapped

来源接口:Debug.getDmabufMappedSizeKb()。含义是当前被进程地址空间映射到的 dma-buf 总量。底层方法是解析每个 /proc/<pid>/maps,找出 dma-buf 映射并累计。它是扫全进程 maps 得到的。

c. unmapped

框架直接算:unmapped = totalExportedDmabuf - dmabufMapped

"DMA-BUF: X (Y mapped + Z unmapped)" 这个打印,其中 X 来自 getDmabufTotalExportedKb(), Y 来自 getDmabufMappedSizeKb(), Z 由 X-Y 计算得到的。


4. DMA-BUF Heaps

DMA-BUF Heaps: 827,108K

(1) 含义:通过 dma-buf heaps 分配器导出的缓冲占用总量。来自 dma_heap 子系统的导出统计(vendor/kernel 实现略有差异)。与上面的 DMA-BUF 有关联,但口径未必完全相同(是否包含所有 exporter、统计时点差异等)。

(2) 它是“DMA-BUF heap exporter 的总导出量(KB)”
Java 层调用:Debug.getDmabufHeapTotalExportedKb()
native 层实现:android_os_Debug_getDmabufHeapTotalExportedKb()
再调用 meminfo 库:meminfo::ReadDmabufHeapTotalExportedKb(&size)

(3) 和 DMA-BUF: 的区别:"DMA-BUF:"是全局导出的 dma-buf 总量, 而"DMA-BUF Heaps:"只看 dma-buf heap 框架导出的总量,是其中的一个子集。


5. DMA-BUF Heaps pool

DMA-BUF Heaps pool: 0K

(1) 含义:dma-buf heaps 的池化预留内存(预分配池)占用。来自 heap pool 统计;值 0K 表示当前无池中预留或平台未启用该池。

(2) 统计方法是 框架 AppProfiler 在汇总内存时调用 Debug.getDmabufHeapPoolsSizeKb()。native JNI 是 android_os_Debug_getDmabufHeapPoolsSizeKb() 然后调用 meminfo::ReadDmabufHeapPoolsSizeKb(&size),返回 KB。

Debug.java 的注释写得比较明确:这个值来自 DMA-BUF heap pool 的内核统计,是读取 /sys/kernel/dma_heap/total_pools_kb 它本质上是“内核已汇总的 heap pool 总量”。

实测,cat /sys/kernel/dma_heap/total_pools_kb 得到的结果也是0.


6. GPU

GPU: 2,483,932K ( 517,164K dmabuf + 1,966,768K private)

(1) 含义:GPU 相关内存总占用。统计来源通常是 GPU 驱动/memtrack:
dmabuf:GPU 使用的共享缓冲(可与系统其他模块共享)。
private:GPU 驱动私有内存(不通过 dmabuf 共享)。

公式:GPU = dmabuf + private。

注意:这行常与 DMA-BUF 有交叉口径(不能简单重复相加到系统总量)。

(2) 统计方法

先取系统视角下的 GPU 总占用(KB), 调用链:AppProfiler -> Debug.getGpuTotalUsageKb -> JNI -> meminfo::ReadGpuTotalUsageKb()

再取 GPU 私有量,调用链:AppProfiler -> Debug.getGpuPrivateMemoryKb() -> JNI. 这个值通常依赖 memtrack HAL 或驱动提供的私有显存统计。

然后 gpu_dmabuf = gpu_total - gpu_private。

这一行是 framework 是通过 Debug JNI + libmeminfo/memtrack 得到的。


7. Used RAM

Used RAM: 12,267,733K (8,291,765K used pss + 3,975,968K kernel)

含义:当前认为“被占用且非空闲”的内存。
统计:
used pss:用户态进程(按 PSS 口径)占用,通常不含 cached pss。
kernel:内核占用(含不可回收与部分可回收口径,依 Android 版本实现有差异)。
公式:Used RAM = used pss + kernel。


8. Lost RAM

Lost RAM: 30,218K

含义:无法被上面分类精确覆盖的余量(“对账差额”)。
常见来源:保留区、页表/元数据、驱动特殊分配、四舍五入、并发采样时差等。
常见近似:Lost ≈ Total - Free - Used。


9. ZRAM

ZRAM: 600,392K physical used for 2,426,624K in swap (7,271,640K total swap)

含义:压缩交换分区(zram)状态。

其中:
physical used:zram 实际占用物理内存(压缩后)。
in swap:已换出到 swap 的逻辑数据量(压缩前)。对照 cat /proc/meminfo 看,其值等于 "SwapTotal" - "SwapFree".
total swap:系统配置的总 swap 容量, 对应 meminfo 的 “SwapTotal”。

压缩比 = in swap / physical used = 2,426,624 / 600,392 ≈ 4.04。


10. Tuning

Tuning: 256 (large 512), oom 322,560K, restore limit 107,520K (high-end-gfx)

(1) 含义:AMS/LMKD 的内存策略参数。

成员解释:
256:普通应用 memory class(MB)。
large 512:声明 largeHeap 应用可用的较大 heap class(MB)。
oom 322,560K:触发更激进回收/杀进程的关键阈值(与 minfree 档位相关)。
restore limit 107,520K:从“紧张状态”恢复时的阈值。
high-end-gfx:设备内存/图形能力档位标签(高端图形配置)。


(2) memory class解释

“普通应用 memory class (MB)” 指的是 Android 给普通应用进程设定的“建议 Java 堆大小上限档位”。可以把它理解为它是一个“内存预算值”。例如 256 就表示该设备上普通 app 的推荐堆大小是约 256MB。App 可以通过 ActivityManager.getMemoryClass() 读到这个值。

它主要针对 Java/Kotlin 堆(Dalvik/ART heap),不是整个进程的全部内存上限。native 内存、图形内存、映射内存等不直接算在这个值里。

堆持续增长到接近 VM 的 heap limit 时,更容易频繁 GC。再继续申请可能触发 OutOfMemoryError。系统内存紧张时,进程也更容易被 LMKD 回收(尤其后台)。

与 large 的区别是:memory class 是普通应用默认档位。large(如 large 512) 是声明 android:largeHeap="true" 的应用可拿到更高堆档位,对应 getLargeMemoryClass()。但 largeHeap 不是“无限内存”,也不保证一定能稳定拿满。

(3) 此版本 cat /proc/zoneinfo 看 min、low、high 水线分别为 73728KB、134544KB、195360KB。不是和这里对应的。
这个 oom 322,560K 是 ProcessList 里算出来的 LMKD minfree 阈值,阈值在 ProcessList.updateOomLevels(...) 里生成,系统先算一个缩放系数 scale(由总内存和分辨率共同决定)。再把每个 OOM 档位的 mOomMinFree[i] 从 low/high 模板插值得到。


11. 小结

(1) 这些行里有很多“子集关系”(例如 GPU dmabuf 属于 DMA-BUF 的一部分、DMA-BUF 又常落在 kernel 口径里),所以不要把所有行直接相加。
(2) Android 版本和厂商内核会改统计方法,字段名字相同也可能细节不同。做问题定位时建议同一机型同一版本横向对比趋势,而不是只看单次绝对值。

 

 

 

 

 

优秀BK:

dumpsys meminfo 的原理和应用: https://www.cnblogs.com/Linux-tech/p/12961295.html

 

posted on 2024-10-16 21:15  Hello-World3  阅读(385)  评论(0)    收藏  举报

导航