Memory 基础知识介绍

  • Post author:
  • Post category:其他



Memory 知识介绍


目录


一、内存分布


二、Reserved Memory


2.1 Reserverd Memory


2.2 kernel Reserved memory


2.3 临时 Reserved memory


2.3.1 Ramdisk


2.3.2 logo reserved memory


2.4 Reserved Memory 查看


三、User space 使用内存


3.1 进程中常用概念


3.1.1 VSS


3.1.2 RSS


3.1.3 PSS


3.1.4 USS


3.1.5 Swap


3.1.6 Pswap


3.1.7 Uswap


3.2 进程地址空间信息


3.3 进程使用内存统计


3.3.1 procrank


3.3.2 proc/meminfo


3.3.3 dumpsys meminfo


四、Kernel space 使用内存


4.1 Kernel Common


4.1.1 Vmalloc


4.1.2 Slab(slub)


4.1.3 Kernel stack


4.1.4 Pagetables


4.2 Drivers


4.2.1 ZRAM 使用 mem 的信息


4.2.2 GPU 使用 mem 的信息


4.2.3 ION(multi-media) 使用 mem 的信息


一、内存分布

Android 系统的内存通常分两种 ROM 和 RAM;ROM 放着 android 各种 image ,通常有 boot /system /data /vendor 等分区;Haps/zebu 等项目中 RAM 模拟 ROM,本文不做详细介绍。本文着重介绍 RAM,就是通常所说的 DDR。

物理内存通常分两大部分, 第一部分 memblock 分配出来的 reserved memory, 另一部分是通过 buddy 分配的,其大小标记为 memtotal(通过 cat proc/meminfo 可以查看)。buddy 分配出的内存根据用途可以分为 User Space 使用的内存 和 Kernel Space 使用的内存。

在 android 系统中 ro.boot.ddrsize 这个属性记录了系统整个 ddr 的大小; 也称之为物理内存的大小。其数值在 uboot 中获取, 通过 kernel 传递给 init 进程,记录在 ro.boot.ddrsize 和 ro.ramsize 这两个属性中。 所以有以下公式:ddrsize = reservedSize + memtotal。

二、Reserved Memory

Uboot 将加载或修改 dts 文件 reserved 的 memory 信息(base 和 size), 然后作为参数传递到 start_kernel() 函数中;解析这些参数后, 通过 memblock 内存分配器申请物理内存。uboot 还更新信息: Kernel 的 位置和大小、ramdisk 的位置和大小。如果 MemTotal 较小,则需要进一步调查 Reserved Memory 的使用情况。

2.1 Reserverd Memory

设计原则是尽量连续,按照项目 MRD 确定 modem,TOS,Audio,sensorHub, WCN/GNSS, WideVine 等子系统预留物理内存的 base 和 size,最终生成一个文档。该文档在 kernel 中以 dts 文件表示。

2.2 kernel Reserved memory

Kernel image 占用的起始物理地址,在 Arm32 是 0x80008000,而 Arm64 是 0x80080000,在 kernel 启动后init 部分会被释放,通常 Kernel resrved memory 分三部分:


  1. Kernel data & code

Kernel image 中不含已经释放的 init 段最终 reserved 的 memory,通常通过 proc/iomem 来查看。

cat proc/iomem | grep Kernel

  80080000-8103ffff : Kernel code
  81490000-81939fff : Kernel data

  1. Kernel PageStruct

这是物理内存的管理成本;物理内存是通过分页机制进行管理,通常物理页的大小是 4K。kmemmap reserved 的 memory 管理所有 DDR 中的物理页的数据结构( struct page) ;在 flat 和 sparse 内存模型中其大小计算方法相同如下:Ddrsize / 4K * sizeof(Struct page)。


  1. Kernel other

Kernel init 常用的数据结构如:pid 的 hash 表等杂项,可以在使用 dumpstack()函数确认,由于总体占用内存不多约几 M。其 size 的计算方法是:KernelOther = DDRSIZE – Memtotal – Sum ( 1.1.1 DTS ) – KernelData&Code – KernelPageStruct

2.3 临时 Reserved memory

这种类型的 reseved memory 显著的特点是用完之后释放,常见两个模块:Ramdisk 和 Logo Buffer。在计算reserved memory 大小时,该类型的内存不能统计在内。

2.3.1 Ramdisk

其释放内存的 log 如下:Freeing initrd memory。

2.3.2 logo reserved memory

Logo buffer 的物理地址要和 UBOOT 的 logo buffer 物理地址保持一致 ; kernel 开机刷新第一个屏幕时释放该 预留内存,其开始地址 0x9E000000,Size 4K Align。其释放内存的 log 如下:Freeing logo memory。

2.4 Reserved Memory 查看

通过使用 memblock 分配器,在 kernel 初始化时可以知道 reserve 物理内存的信息,因此 memblock 就能完整的展现 Android 平台上物理内存的布局。

Memblock 如下,有两项:ls /sys/kernel/debug/memblock

agn9190SYO_q6215:/ # ls /sys/kernel/debug/memblock
memory  reserved


Memory

显示整个平台所有的物理内存。比如下面的系统物理内存为

系统物理内存大小是由 uboot 通过自动检测得到。通过 dts 文件中 memory 节点的描述用于 sysdump。


Reserved

显示整个平台被 reserved 的物理内存,如果有连续的物理内存段会自动合并。

cat /sys/kernel/debug/memblock/reserved

agn9190SYO_q6215:/ # cat /sys/kernel/debug/memblock/reserved
   0: 0x0000000080000000..0x0000000080000fff
   1: 0x0000000080080000..0x0000000081936fff
   2: 0x0000000081938000..0x0000000081939fff
   3: 0x0000000082000000..0x0000000082043bae
   4: 0x0000000082100000..0x00000000829dbfff
   5: 0x0000000087400000..0x000000008defffff
   6: 0x0000000094000000..0x0000000099ffffff
   7: 0x000000009e000000..0x000000009e9e3fff
   8: 0x00000000efaae000..0x00000000f40adfff
   9: 0x00000000fd6c8000..0x00000000fffbffff
  10: 0x00000000ffff7000..0x00000000ffffefff
  11: 0x00000000ffffff00..0x00000000ffffff3f
  12: 0x00000000ffffff80..0x00000000ffffffbf
  13: 0x0000000100000000..0x0000000100000fff
  14: 0x000000017b600000..0x000000017fbfffff
  15: 0x000000017fd3a000..0x000000017fd3afff
  16: 0x000000017fe86000..0x000000017fe86fff
  17: 0x000000017fe87b80..0x000000017fe8ff87
  18: 0x000000017fe90000..0x000000017ff37fff
  19: 0x000000017ff38180..0x000000017ff3821f
  20: 0x000000017ff38280..0x000000017ff386e8
  21: 0x000000017ff38700..0x000000017ff38887
  22: 0x000000017ff38900..0x000000017ff38a7f
  23: 0x000000017ff39000..0x000000017ff39fff
  24: 0x000000017ff3aa80..0x000000017ff3af5d
  25: 0x000000017ff3af80..0x000000017ff3b45d
  26: 0x000000017ff3b480..0x000000017ff3e47f
  27: 0x000000017ff3e4b8..0x000000017fffe03b
  28: 0x000000017fffe080..0x000000017fffe0e8
  29: 0x000000017fffe100..0x000000017fffe23f
  30: 0x000000017fffe280..0x000000017fffe29f
  31: 0x000000017fffe300..0x000000017fffe307
  32: 0x000000017fffe380..0x000000017fffe85d
  33: 0x000000017fffe880..0x000000017fffe987
  34: 0x000000017fffe9d0..0x000000017fffe9fe
  35: 0x000000017fffea00..0x000000017fffea2e
  36: 0x000000017fffea30..0x000000017fffea63
  37: 0x000000017fffea68..0x000000017fffea9e
  38: 0x000000017fffeaa0..0x000000017fffead6
  39: 0x000000017fffead8..0x000000017fffeb04
  40: 0x000000017fffeb08..0x000000017fffeb34
  41: 0x000000017fffeb38..0x000000017fffeb64
  42: 0x000000017fffeb68..0x000000017fffeb94
  43: 0x000000017fffeb98..0x000000017fffebc4
  44: 0x000000017fffebc8..0x000000017fffebf4
  45: 0x000000017fffebf8..0x000000017fffec24
  46: 0x000000017fffec28..0x000000017fffec54
  47: 0x000000017fffec58..0x000000017fffec84
  48: 0x000000017fffec88..0x000000017fffecb4
  49: 0x000000017fffecb8..0x000000017fffece4
  50: 0x000000017fffece8..0x000000017fffed14
  51: 0x000000017fffed18..0x000000017fffed44
  52: 0x000000017fffed48..0x000000017fffed74
  53: 0x000000017fffed78..0x000000017fffedaa
  54: 0x000000017fffedb0..0x000000017fffede2
  55: 0x000000017fffede8..0x000000017fffee1a
  56: 0x000000017fffee20..0x000000017fffee4b
  57: 0x000000017fffee50..0x000000017fffee7b
  58: 0x000000017fffee80..0x000000017fffeeab
  59: 0x000000017fffeeb0..0x000000017fffeedb
  60: 0x000000017fffeee0..0x000000017fffef0b
  61: 0x000000017fffef10..0x000000017fffef3b
  62: 0x000000017fffef40..0x000000017fffef6b
  63: 0x000000017fffef70..0x000000017fffef9b
  64: 0x000000017fffefa0..0x000000017fffefcb
  65: 0x000000017fffefd0..0x000000017fffeffb

三、User space 使用内存

进程使用内存,又分为两大类:(这两大类都会在进程地址空间中得到体现)


  1. 常规内存

    :指的是某进程进行匿名映射,或者文件映射,或者读写文件 的缓存,或者普通 malloc,free 等等常规使用和运行时用到的 mem。可以看内核函数 vm_normal_page 的实现和注释。


  2. 特殊内存

    :一些特殊的,使用物理内存直接 mmap 到用户空间的内存;或者由内核模块配合分配,然后 mmap到用户空间的内存。比如,该进程使用的 mali 分配的内存,ION 分配的内存,或者可以的 framebuffer 的内存,等等(寄存器也是可以映射的,这些都不作为物理的 ddr mem)。

3.1 进程中常用概念

3.1.1 VSS

是单个进程全部可访问的用户虚拟地址空间。

其大小包括可能还尚未在内存中驻留的部分,比如地址空间已经被 malloc 申请,但是还没有分配。VSS 为程所有vma 段大小之和,包括常规内存和特殊内存。所以当一个进程的 VSS 特别大时,可能有两种异常情况,通过检查进程的 maps 或者 procmem,可以区分内存泄漏或者不断的映射特殊内存但是不释放映射,从而导致进程虚拟空间耗尽。

3.1.2 RSS

单个进程实际占用的内存大小

RSS 易被误导的原因在于,它包括了该进程所使用的所有共享库的全部内存大小。对于单个共享库,尽管无论多少个进程使用,实际该共享库只会被装入内存一次。对于单个进程的内存使用大小, RSS 不是一个精确的描述。

3.1.3 PSS

按比例包含其所使用的共享库大小。

PSS 是一个非常有用的数字,因为系统中全部进程以整体的方式被统计, 对于系统中的整体内存使用是一个很好的描述。如果一个进程被终止, 其 PSS 中所使用的共享库大小将会重新按比例分配给剩下的仍在运行并且仍在 使用该共享库的进程。此种计算方式有轻微的误差,因为当某个进程中止的 时候, PSS 没有精确的表示被返还给整个系统的内存大小也就是说一个进 程死掉后,并不一定能释放所有的 PSS(但是最终可能会对 PSS 对应内存的 释放带来影响)。计算的时候每个进程占的比例为 page/page->mapcount。

3.1.4 USS

是单个进程的全部私有内存大小。

USS 是一个非常非常有用的数字, 因为它揭示了运行一个特定进程的真实的内存增量大小。如果进程被终止, USS 就是实际被返还给系统的内存大小。USS 是针对某个进程开始有可疑内存泄露的情况,进行检测的最佳数字。

3.1.5 Swap

不常用的匿名 page 会被交换到 swap 分区。某个进程被交换出去的匿名页的大小就是 Swap(包括在 swap cache 中的和真正交换到 swap 分区的 都算)。

3.1.6 Pswap

模仿 PSS 的概念,因为每个匿名页可能会被多个进程使用。因此 Swap 中的 page 照目前还有多少进程使用它,按照比例分配得到 pswap。

3.1.7 Uswap

模仿 Uss 的概念,私有的且被 swap 出去的内存的大小。

3.2 进程地址空间信息


/proc/pid/smaps

这个是对进程地址空间以及内存使用,最全面的展示。代码实现在内核的 fs/proc/task_mmu.c。以 systemUI 进程为例,adb shell cat /proc/pid/smaps,内容较多,仅显示一两处:

7f501ec000-7f501ed000 rw-p 00002000 fd:04 2419                           /system/lib64/libion.so
Size:                  4 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Rss:                   4 kB
Pss:                   4 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         4 kB
Referenced:            0 kB
Filecache:               0 kB
Pss_Filecache:           0 kB
Shared_Filecache:        0 kB
Private_Filecache:       0 kB
Anonymous:             4 kB
Pss_Anonymous:           4 kB
Shared_Anonymous:        0 kB
Private_Anonymous:       4 kB
LazyFree:              0 kB
AnonHugePages:         0 kB
ShmemPmdMapped:        0 kB
Shared_Hugetlb:        0 kB
Private_Hugetlb:       0 kB
Swap:                  0 kB
SwapPss:               0 kB
USwap:                 0 kB
Locked:                0 kB
VmFlags: rd wr mr mw me ac
7f501ed000-7f501ef000 r--s 00000000 fd:04 1240                           /system/fonts/NotoSansCarian-Regular.ttf
Size:                  8 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Rss:                   0 kB
Pss:                   0 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         0 kB
Referenced:            0 kB
Filecache:               0 kB
Pss_Filecache:           0 kB
Shared_Filecache:        0 kB
Private_Filecache:       0 kB
Anonymous:             0 kB
Pss_Anonymous:           0 kB
Shared_Anonymous:        0 kB
Private_Anonymous:       0 kB
LazyFree:              0 kB
AnonHugePages:         0 kB
ShmemPmdMapped:        0 kB
Shared_Hugetlb:        0 kB
Private_Hugetlb:       0 kB
Swap:                  0 kB
SwapPss:               0 kB
USwap:                 0 kB
Locked:                0 kB

3.3 进程使用内存统计

进程统计方法很多,通常是使用 procrank,proc/meminfo,dumsys meminfo 等。

3.3.1 procrank

可以展示一个进程的所有的常规内存信息。缺点是遍历 proc 下所有进程导致执行比较耗。在打开了 swap 的情况下,通过检查某个进程的下述信息可以大概判断是否内存泄漏。比如 VSS,RSS 特别大,或者 RSS+Swap (使用 PSS+PSwap 要更准确一些)特别大。

agn9190SYO_q6215:/ # procrank
  PID       Vss      Rss      Pss      Uss     Swap    PSwap    USwap    ZSwap  cmdline
 1015  17476104K  428000K  194763K  126240K      60K       1K       0K       0K  system_server
 2094  15115124K  295100K  165367K  148776K      60K       1K       0K       0K  com.android.systemui
 2308  1637400K  258308K  136988K  108644K      40K       2K       0K       0K  com.freeme.launcher
 5634  14564760K  176964K   72490K   65176K     192K      93K      52K      18K  com.huawei.hwid.core
 2052  14650008K  160448K   56803K   49688K      60K       1K       0K       0K  com.android.phone
 ……
                            ------   ------   ------   ------   ------   ------  ------
                          1643443K  1226872K  439220K  107588K   59068K   20952K  TOTAL
​
ZRAM: 22584K physical used for 115968K in swap (2266988K total swap)
 RAM: 3778320K total, 235064K free, 3156K buffers, 2044696K cached, 7704K shmem, 180060K slab

3.3.2 proc/meminfo

该节点显示内存状态信息,它显示出系统中空闲内存, 已用物理内存和交换内存的总量,还显示出内核使用的共享内存和缓冲区总量。这些信息的格式和free 命令显示的结果类似。

adb shell cat /proc/meminfo
MemTotal:        3780444 kB // user space 和 kernel space 可用的总内存
MemFree:          214284 kB // buddy 里面所有 free 的 page 的数
MemAvailable:    1401224 kB // 系统当前可使用的内存
Buffers:            1360 kB // 块设备的缓存页(不属于某个具体文件的管理信息的缓存页)
Cached:          1313764 kB // 属于具体某个文件的缓存页
SwapCached:        92020 kB // swap cache 中的缓存页
Active:          1711472 kB // lru 中正在使用中的且使用的较积极的页
Inactive:         878528 kB // lru 中正在使用中的但是不太积极的页
Active(anon):    1071032 kB // Active 的文件匿名页
Inactive(anon):   343108 kB // Inactive 的文件匿名页
Active(file):     640440 kB // Active 的文件缓存页
Inactive(file):   535420 kB // Inactive 的文件缓存页
Unevictable:      121364 kB // 隔离的,暂时不参与 active/Inactive 判断的匿名页和文件缓存页之合
Mlocked:          121364 kB // 锁定在内存,不交互也不 drop
SwapTotal:       2268260 kB // swap 分区总大小(对于 zram,是 zram 块设备的大小)
SwapFree:        1674084 kB // swap 分区 free 空间(对于 zram,是 zram 块设备剩余空间)
Dirty:               392 kB // 文件缓存中的脏页,如果这个地方很大,需 check IO 有问题
Writeback:             0 kB // 文件缓存中正在写回的页
AnonPages:       1391868 kB // APP 所使用的匿名映射的 pages(没有被 swap 出去的部分)
Mapped:           647752 kB // mapped 文件的部分,其应该是 cached 的一个子集
Shmem:             18572 kB // 共享内存
KReclaimable:      86308 kB 
Slab:             188200 kB // slab 占有的所有 page. 如果 debug 版本打开了 slub 将显著的增大该项
SReclaimable:      60244 kB // 其中设置为 Reclaimable 的 slab 占用的部分
SUnreclaim:       127956 kB // 设置为 Unreclaim 的 slab 占用的部分
KernelStack:       51536 kB // 每个线程(无论用户线程还是内核线程)都有一个 8K 的内核空间线程栈
PageTables:        71744 kB // 用户进程的二级页表 pte 项,所以可以认为完全是用户态占用
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     4158480 kB
Committed_AS:   70169112 kB
VmallocTotal:   263061440 kB // 内核 vmalloc 可以用的全部空间(虚拟地址)
VmallocUsed:       91644 kB  // 内核 vmalloc 使用的物理内存大小
VmallocChunk:          0 kB
PActive(anon):         0 kB
PInactive(anon):       0 kB
PActive(file):       140 kB
PInactive(file):       0 kB

3.3.3 dumpsys meminfo

只是列出了进程当前的 PSS 值,不过能看到进程分类,以及当前进程 framework AMS 定义的 OOM_adj 的档位,在 Android R 后加入了 RSS 值的显示。

Total RSS by process:
……
​
Total RSS by OOM adjustment:
……
    382,972K: System
        382,972K: system (pid 884)
    782,492K: Persistent
……
  1,037,376K: Foreground
……
  1,293,852K: Visible
……
    294,612K: Perceptible
……
  1,013,872K: B Services
……
​
Total RSS by category:
……
​
Total PSS by process:
    273,032K: com.ss.android.article.lite (pid 19053)
    190,760K: system (pid 884)
    166,948K: com.tencent.qqmusic (pid 13291 / activities)
    137,833K: com.android.launcher (pid 2133 / activities)
     81,922K: com.huawei.hwid.core (pid 9489)
     79,903K: com.tencent.qqmusic:QQPlayerService (pid 13448)
     79,695K: com.android.systemui (pid 1889)
     58,298K: com.ss.android.article.lite:miniapp0 (pid 20076)
     55,928K: com.android.settings (pid 2286 / activities)
     53,710K: com.ss.android.article.lite:push (pid 18989)
     53,279K: com.icoolme.android.weather (pid 18466)
     53,175K: com.ss.android.article.lite:pushservice (pid 19765)
     51,489K: com.iflytek.inputmethod (pid 2954)
     50,710K: android.hardware.audio.service (pid 459)
     44,717K: com.huawei.hwid.container2 (pid 10774)
     44,299K: com.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0 (pid 5666)
     42,806K: com.android.phone (pid 1851)
     37,520K: com.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0 (pid 14566)
     34,758K: com.android.permissioncontroller (pid 8176)
     34,245K: com.google.android.providers.media.module (pid 2623)
     30,909K: com.android.networkstack.process (pid 2095)
     30,523K: com.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0 (pid 3616)
     30,379K: com.huawei.hwid.persistent (pid 8673)
     23,034K: com.huawei.hwid.container1 (pid 9589)
     22,745K: com.google.android.tts (pid 2899)
     21,005K: com.iflytek.inputmethod.assist (pid 3101)
     20,060K: com.freeme.ota (pid 3271)
     20,012K: com.freeme.gallery (pid 10768)
     19,338K: com.android.phone (pid 4190)
     16,294K: surfaceflinger (pid 500)
     13,931K: audioserver (pid 491)
     10,075K: com.android.creator (pid 9892)
      9,929K: com.android.messaging (pid 11235)
      9,565K: com.android.keychain (pid 18373)
      9,396K: vendor.sprd.hardware.gnss@2.1-service (pid 644)
      9,284K: com.android.webview:webview_service (pid 12770)
      9,025K: com.android.dialer (pid 3959)
      8,844K: zygote (pid 454)
      8,362K: com.freeme.hongbaoassistant (pid 3857)
      8,345K: zygote64 (pid 453)
      8,132K: com.android.deskclock (pid 2181)
      7,826K: com.android.settings:CryptKeeper (pid 2473)
      7,734K: com.sprd.dm.mbselfreg:DmSmsService (pid 4601)
      7,713K: com.spreadtrum.vce (pid 2451)
      7,409K: com.android.contacts (pid 3988)
      7,391K: cp_diskserver (pid 859)
      7,381K: com.freeme.provider.badge (pid 10081)
      7,268K: com.droi.pedometer (pid 2662)
      7,068K: com.freeme.bio.face.service (pid 4721)
      6,948K: com.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0 (pid 19461)
      6,273K: android.hardware.graphics.composer@2.1-service (pid 467)
      5,652K: webview_zygote (pid 2062)
      5,633K: com.android.smspush (pid 2853)
      5,613K: com.android.modemnotifier (pid 2686)
      5,546K: mediaserver (pid 609)
      5,265K: logd (pid 314)
      4,702K: init (pid 1)
      4,603K: android.hardware.camera.provider@2.4-service (pid 461)
      4,340K: android.hardware.drm@1.3-service.widevine (pid 464)
      4,253K: media.extractor (pid 607)
      4,151K: media.codec (pid 628)
      3,793K: vendor.sprd.hardware.face@1.0-service (pid 482)
      3,732K: cameraserver (pid 594)
      3,508K: netd (pid 452)
      3,152K: media.swcodec (pid 645)
      3,061K: urild (pid 519)
      2,952K: vendor.unisoc.hardware.power-service (pid 477)
      2,179K: ueventd (pid 285)
      2,136K: installd (pid 604)
      2,136K: vold (pid 328)
      1,988K: media.metrics (pid 608)
      1,987K: keystore (pid 605)
      1,812K: statsd (pid 451)
      1,796K: init (pid 283)
      1,769K: hwservicemanager (pid 317)
      1,707K: android.hardware.neuralnetworks@1.2-service-xtensa (pid 470)
      1,671K: adbd (pid 5837)
      1,527K: engpc (pid 504)
      1,523K: wificond (pid 616)
      1,491K: servicemanager (pid 316)
      1,486K: vendor.sprd.hardware.enhance@1.0-service (pid 481)
      1,462K: android.hardware.graphics.allocator@4.0-service (pid 466)
      1,431K: modem_control (pid 509)
      1,404K: android.hardware.keymaster@4.1-unisoc.service (pid 371)
      1,398K: android.hardware.drm@1.3-service.clearkey (pid 463)
      1,340K: android.hardware.biometrics.fingerprint@2.1-service (pid 651)
      1,292K: ylog (pid 441)
      1,279K: update_engine (pid 648)
      1,268K: drmserver (pid 598)
      1,244K: android.hardware.wifi@1.0-service (pid 474)
      1,228K: credstore (pid 492)
      1,214K: thermald (pid 638)
      1,204K: android.system.suspend@1.0-service (pid 370)
      1,200K: gpuservice (pid 496)
      1,117K: gatekeeperd (pid 646)
      1,112K: ip6tables-restore (pid 495)
      1,108K: storaged (pid 614)
      1,108K: iptables-restore (pid 494)
      1,073K: android.hardware.sensors@1.0-service (pid 472)
      1,051K: vendor.sprd.hardware.boot@1.1-service (pid 372)
      1,039K: android.hardware.health@2.1-service (pid 468)
        974K: vendor.freeme.hardware.soul@1.0-service (pid 639)
        970K: android.hardware.usb@1.1-service (pid 473)
        966K: incidentd (pid 603)
        957K: linkturbonative (pid 621)
        930K: dumpsys (pid 20251)
        918K: android.hardware.cas@1.2-service (pid 462)
        916K: android.hardware.power.stats@1.0-service.mock (pid 471)
        887K: vendor.sprd.hardware.thermal@2.0-service (pid 487)
        879K: connmgr (pid 654)
        860K: vendor.sprd.hardware.network@1.0-service (pid 485)
        858K: refnotify (pid 632)
        854K: vendor.sprd.hardware.log@1.0-service (pid 484)
        854K: vendor.sprd.hardware.broadcastradio@2.0-service (pid 478)
        846K: android.hardware.memtrack@1.0-service (pid 469)
        842K: srtd (pid 634)
        838K: vendor.sprd.hardware.cplog_connmgr@1.0-service (pid 480)
        833K: vendor.sprd.hardware.vibrator-service (pid 490)
        829K: lmkd (pid 315)
        824K: vendor.sprd.hardware.fingerprintmmi@1.0-service (pid 483)
        819K: vendor.sprd.hardware.lights-service (pid 475)
        819K: android.hardware.bluetooth@1.1-service.unisoc (pid 460)
        818K: ftt_service (pid 493)
        811K: vendor.sprd.hardware.connmgr@1.0-service (pid 479)
        800K: vendor.sprd.hardware.wcn@1.0-service (pid 489)
        788K: android.hardware.rebootescrow-service.default (pid 476)
        783K: android.hardware.gatekeeper@1.0-service.trusty (pid 465)
        778K: modemlog_connmgr_service (pid 610)
        762K: ip (pid 624)
        748K: performancemanager (pid 497)
        732K: sprd_networkcontrol (pid 622)
        724K: android.hidl.allocator@1.0-service (pid 458)
        714K: slogmodem (pid 611)
        709K: log_service (pid 606)
        703K: phasecheckserver (pid 631)
        670K: traced (pid 552)
        642K: traced_probes (pid 551)
        640K: tsupplicant (pid 516)
        614K: ylogw (pid 591)
        587K: mlogservice (pid 630)
        587K: sprdstorageproxyd (pid 655)
        577K: gpsd (pid 507)
        575K: sprdstorageproxyd (pid 514)
        542K: sh (pid 620)
        534K: sh (pid 625)
        532K: ims_bridged (pid 619)
        506K: ext_data (pid 618)
        506K: tombstoned (pid 440)
​
Total PSS by OOM adjustment:
    265,529K: Native
         50,710K: android.hardware.audio.service (pid 459)
         16,294K: surfaceflinger (pid 500)
         13,931K: audioserver (pid 491)
          9,396K: vendor.sprd.hardware.gnss@2.1-service (pid 644)
          8,844K: zygote (pid 454)
          8,345K: zygote64 (pid 453)
          7,391K: cp_diskserver (pid 859)
          6,273K: android.hardware.graphics.composer@2.1-service (pid 467)
          5,652K: webview_zygote (pid 2062)
          5,546K: mediaserver (pid 609)
          5,265K: logd (pid 314)
          4,702K: init (pid 1)
          4,603K: android.hardware.camera.provider@2.4-service (pid 461)
          4,340K: android.hardware.drm@1.3-service.widevine (pid 464)
          4,253K: media.extractor (pid 607)
          4,151K: media.codec (pid 628)
          3,793K: vendor.sprd.hardware.face@1.0-service (pid 482)
          3,732K: cameraserver (pid 594)
          3,508K: netd (pid 452)
          3,152K: media.swcodec (pid 645)
          3,061K: urild (pid 519)
          2,952K: vendor.unisoc.hardware.power-service (pid 477)
          2,179K: ueventd (pid 285)
          2,136K: installd (pid 604)
          2,136K: vold (pid 328)
          1,988K: media.metrics (pid 608)
          1,987K: keystore (pid 605)
          1,812K: statsd (pid 451)
          1,796K: init (pid 283)
          1,769K: hwservicemanager (pid 317)
          1,707K: android.hardware.neuralnetworks@1.2-service-xtensa (pid 470)
          1,671K: adbd (pid 5837)
          1,527K: engpc (pid 504)
          1,523K: wificond (pid 616)
          1,491K: servicemanager (pid 316)
          1,486K: vendor.sprd.hardware.enhance@1.0-service (pid 481)
          1,462K: android.hardware.graphics.allocator@4.0-service (pid 466)
          1,431K: modem_control (pid 509)
          1,404K: android.hardware.keymaster@4.1-unisoc.service (pid 371)
          1,398K: android.hardware.drm@1.3-service.clearkey (pid 463)
          1,340K: android.hardware.biometrics.fingerprint@2.1-service (pid 651)
          1,292K: ylog (pid 441)
          1,279K: update_engine (pid 648)
          1,268K: drmserver (pid 598)
          1,244K: android.hardware.wifi@1.0-service (pid 474)
          1,228K: credstore (pid 492)
          1,214K: thermald (pid 638)
          1,204K: android.system.suspend@1.0-service (pid 370)
          1,200K: gpuservice (pid 496)
          1,117K: gatekeeperd (pid 646)
          1,112K: ip6tables-restore (pid 495)
          1,108K: storaged (pid 614)
          1,108K: iptables-restore (pid 494)
          1,073K: android.hardware.sensors@1.0-service (pid 472)
          1,051K: vendor.sprd.hardware.boot@1.1-service (pid 372)
          1,039K: android.hardware.health@2.1-service (pid 468)
            974K: vendor.freeme.hardware.soul@1.0-service (pid 639)
            970K: android.hardware.usb@1.1-service (pid 473)
            966K: incidentd (pid 603)
            957K: linkturbonative (pid 621)
            930K: dumpsys (pid 20251)
            918K: android.hardware.cas@1.2-service (pid 462)
            916K: android.hardware.power.stats@1.0-service.mock (pid 471)
            887K: vendor.sprd.hardware.thermal@2.0-service (pid 487)
            879K: connmgr (pid 654)
            860K: vendor.sprd.hardware.network@1.0-service (pid 485)
            858K: refnotify (pid 632)
            854K: vendor.sprd.hardware.log@1.0-service (pid 484)
            854K: vendor.sprd.hardware.broadcastradio@2.0-service (pid 478)
            846K: android.hardware.memtrack@1.0-service (pid 469)
            842K: srtd (pid 634)
            838K: vendor.sprd.hardware.cplog_connmgr@1.0-service (pid 480)
            833K: vendor.sprd.hardware.vibrator-service (pid 490)
            829K: lmkd (pid 315)
            824K: vendor.sprd.hardware.fingerprintmmi@1.0-service (pid 483)
            819K: vendor.sprd.hardware.lights-service (pid 475)
            819K: android.hardware.bluetooth@1.1-service.unisoc (pid 460)
            818K: ftt_service (pid 493)
            811K: vendor.sprd.hardware.connmgr@1.0-service (pid 479)
            800K: vendor.sprd.hardware.wcn@1.0-service (pid 489)
            788K: android.hardware.rebootescrow-service.default (pid 476)
            783K: android.hardware.gatekeeper@1.0-service.trusty (pid 465)
            778K: modemlog_connmgr_service (pid 610)
            762K: ip (pid 624)
            748K: performancemanager (pid 497)
            732K: sprd_networkcontrol (pid 622)
            724K: android.hidl.allocator@1.0-service (pid 458)
            714K: slogmodem (pid 611)
            709K: log_service (pid 606)
            703K: phasecheckserver (pid 631)
            670K: traced (pid 552)
            642K: traced_probes (pid 551)
            640K: tsupplicant (pid 516)
            614K: ylogw (pid 591)
            587K: mlogservice (pid 630)
            587K: sprdstorageproxyd (pid 655)
            577K: gpsd (pid 507)
            575K: sprdstorageproxyd (pid 514)
            542K: sh (pid 620)
            534K: sh (pid 625)
            532K: ims_bridged (pid 619)
            506K: ext_data (pid 618)
            506K: tombstoned (pid 440)
    190,760K: System
        190,760K: system (pid 884)
    191,576K: Persistent
         79,695K: com.android.systemui (pid 1889)
         42,806K: com.android.phone (pid 1851)
         30,909K: com.android.networkstack.process (pid 2095)
         11,464K: com.freeme.provider.config (pid 2222)
          7,713K: com.spreadtrum.vce (pid 2451)
          7,268K: com.droi.pedometer (pid 2662)
          6,108K: com.mdid.msa (pid 2646)
          5,613K: com.android.modemnotifier (pid 2686)
     34,245K: Persistent Service
         34,245K: com.google.android.providers.media.module (pid 2623)
    489,610K: Foreground
        273,032K: com.ss.android.article.lite (pid 19053)
    424,119K: Visible
         84,421K: com.freeme.secureguard (pid 3454)
         81,922K: com.huawei.hwid.core (pid 9489)
         53,710K: com.ss.android.article.lite:push (pid 18989)
         53,175K: com.ss.android.article.lite:pushservice (pid 19765)
         44,299K: com.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0 (pid 5666)
         30,523K: com.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0 (pid 3616)
         30,379K: com.huawei.hwid.persistent (pid 8673)
         23,034K: com.huawei.hwid.container1 (pid 9589)
         10,075K: com.android.creator (pid 9892)
          6,948K: com.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0 (pid 19461)
          5,633K: com.android.smspush (pid 2853)
     85,481K: Perceptible
         51,489K: com.iflytek.inputmethod (pid 2954)
         21,005K: com.iflytek.inputmethod.assist (pid 3101)
         12,987K: com.freeme.widget.newspage (pid 6037)
     19,338K: A Services
         19,338K: com.android.phone (pid 4190)
    466,256K: B Services
        166,948K: com.tencent.qqmusic (pid 13291 / activities)
         79,903K: com.tencent.qqmusic:QQPlayerService (pid 13448)
         55,928K: com.android.settings (pid 2286 / activities)
         20,060K: com.freeme.ota (pid 3271)
          8,362K: com.freeme.hongbaoassistant (pid 3857)
          7,734K: com.sprd.dm.mbselfreg:DmSmsService (pid 4601)
    306,007K: Cached
         53,279K: com.icoolme.android.weather (pid 18466)
         44,717K: com.huawei.hwid.container2 (pid 10774)
         37,520K: com.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0 (pid 14566)
         34,758K: com.android.permissioncontroller (pid 8176)
         22,745K: com.google.android.tts (pid 2899)
         20,012K: com.freeme.gallery (pid 10768)
         12,700K: com.freeme.zmcalendar:channel (pid 11966)
         11,725K: com.freeme.searchbox (pid 10698)
          9,929K: com.android.messaging (pid 11235)
          9,565K: com.android.keychain (pid 18373)
          9,284K: com.android.webview:webview_service (pid 12770)
          9,025K: com.android.dialer (pid 3959)
          8,132K: com.android.deskclock (pid 2181)
          7,826K: com.android.settings:CryptKeeper (pid 2473)
          7,409K: com.android.contacts (pid 3988)
          7,381K: com.freeme.provider.badge (pid 10081)
​
Total PSS by category:
    531,156K: Native
    510,969K: .dex mmap
    280,009K: Dalvik
    157,452K: .so mmap
     96,447K: .apk mmap
     87,843K: Dalvik Other
     80,273K: .art mmap
     61,399K: .jar mmap
     42,835K: Stack
     29,086K: .oat mmap
     26,250K: Unknown
     12,507K: Other mmap
     10,595K: .ttf mmap
      1,756K: Ashmem
      1,493K: Other dev
          0K: Cursor
          0K: Gfx dev
          0K: EGL mtrack
          0K: GL mtrack
          0K: Other mtrack
​
Total RAM: 3,780,444K (status normal)
 Free RAM: 1,352,879K (  306,007K cached pss +   795,892K cached kernel +   250,980K free)
      ION:   172,888K (  101,944K mapped +    40,604K unmapped +    30,340K pools)
 Used RAM: 2,472,654K (2,166,914K used pss +   305,740K kernel)
 Lost RAM:   324,594K
     ZRAM:   173,168K physical used for   584,448K in swap (2,268,260K total swap)
   Tuning: 192 (large 512), oom   387,072K, restore limit   129,024K (high-end-gfx)
  1. Total RAM,同上述的 MemTotal。

  2. Free RAM,Android 将进程按照重要程度进行分类(就是 oom adj 值), 其中优先级最低为 cached 类型。Android 认为这些进程被杀掉(释放内存)也是无所谓的,所以将这部分内存也统计为 Free RAM,再加上 free 和 cached 的 mem。Free RAM: = cahedPss + memInfco.getCachedSizeKb() +memInfo.getFreeSizeKb() = sum(adj>9 进程的 pss) + meminfo(buffers+cached-mapped) + meminfo(memfree)

  3. Used RAM,也不等同于一般的 used 的内存的概念。Android 只将那些优先级小于 Cached 进程所使用的内存认为是使用了的;再加上 shmem,还有 slab 占用的,vmalloc (但 vmalloc 区域也有不占用物理内存的部分), PageTables , KernelStack。其它的比如 ION,MALI,zram 还有很多内核分配的统统的不算。 Used RAM: =totalPss – cachedPss + memInfo.getKernelUsedSizeKb() =sum(adj<9 进程的 pss) + meminfo(shmem + slab + vmallocused + PageTables + KernelStack) 其中 kernel 使用内存: memInfo.getKernelUsedSizeKb() = meminfo(shmem + slab + vmallocused + PageTables + KernelStack)

  4. Lost RAM:Lost RAM = Total RAM – Free RAM – Used RAM。具体这些内存谁使用??应该是内核模块在使用,模块可能是 zram,可以能 GPU,可能是 ION,可能是其它内核模块,这个值有时会得到是负数,是因为这套统计机制是有缺陷的。

  5. ZRAM:zram 模块使用多少物理内存,存储了多少压缩后的 swap 内 存页,整个 swap 分区有多大。 但是上述 Free RAM 和 Used RAM 的算法是有些问题的,有计算重复的 地方。Cached PSS 应该是指所有处于 cached 的 adj 的 APP 的 PSS,而这些 PSS 是包括了文件映射 page 的,这样部分就和 cached 重复了。Cached 的 mem 应该有些也不会体现在 PSS 里面,比如没有人使用了,但是还没有回收 的那些(这些要研读 dumpsys meminfo 的代码实现才能最终确认)。

  6. Dumpsys meminfo 某一个进程比如:这个还是比较有意思的,我们可以看一个进程其各个分类总计是多少,有多少被 swap 出去了,特别是 Native Heap 和 Dalvik Heap, 通过看其 Heap 的状态,可以查是否有内存泄漏。同时也可以知道进程整体的 mem 分类。

adb shell dumpsys meminfo 2133
Applications Memory Usage (in Kilobytes):
Uptime: 2853697 Realtime: 2853697
​
** MEMINFO in pid 2133 [xxxr] **
​
                   Pss  Private  Private  SwapPss      Rss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty    Total     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------   ------
  Native Heap    52668    52552        0     9921    54572    97784    58576    25384
  Dalvik Heap    14207    13936        0      172    17876    33893     9317    24576
 Dalvik Other     5911     3884        0        4     8400
        Stack     1736     1736        0      624     1744
       Ashmem      186      184        0        0      204
    Other dev      148        0      148        0      380
     .so mmap     3656      172        0       49    31388
    .jar mmap     1260        0        0        0    31968
    .apk mmap     2403       56      812      152     9996
    .ttf mmap     4094        0     2340        0     8324
    .dex mmap    22290        4    22144       20    23412
    .oat mmap      885        0        0        0    12056
    .art mmap     3150     2232        0       20    14780
   Other mmap      163        8        0        0     1680
      Unknown      639      632        0      129      880
        TOTAL   124487    75396    25444    11091   124487   131677    67893    49960
​
 App Summary
                       Pss(KB)                        Rss(KB)
                        ------                         ------
           Java Heap:    16168                          32656
         Native Heap:    52552                          54572
                Code:    25536                         121236
               Stack:     1736                           1744
            Graphics:        0                              0
       Private Other:     4848
              System:    23647
             Unknown:                                    7452
​
           TOTAL PSS:   124487            TOTAL RSS:   217660       TOTAL SWAP PSS:    11091
​
 Objects
               Views:      921         ViewRootImpl:        2
         AppContexts:       11           Activities:        1
              Assets:       28        AssetManagers:        0
       Local Binders:       99        Proxy Binders:       82
       Parcel memory:      199         Parcel count:      259
    Death Recipients:        8      OpenSSL Sockets:        6
            WebViews:        0
​
 SQL
         MEMORY_USED:     2854
  PAGECACHE_OVERFLOW:      601          MALLOC_SIZE:      117
​
 DATABASES
      pgsz     dbsz   Lookaside(b)          cache  Dbname
         4      208             59      176/63/25  

四、Kernel space 使用内存

Kernel space 使用内存通常由 kmalloc 和 vmalloc 两种分配,此外还有调用 get_free_page(),alloc_pages()获取物理内存。

4.1 Kernel Common

以下几项指标需在 userroot 或 userdebug 版本获取。

4.1.1 Vmalloc

vmalloc 分配的虚拟内存是连续的,其分配的区间为内存初始化时分配的从 VMALLOC_START 到 VMALLOC_END 区间,分配的虚拟内存时以 PAGE_SIZE 对齐的。如果有物理内存,则物理内存是不连续的。使用 vm_struct 来描述 vmalloc 区域。可以通过 cat proc/vmallocinfo 查看。

K4.14 等 arm64 bit 上默认 CONFIG_VMAP_STACK 打开; 所以 vmall oc info 中会含有 kernel stack 使用的物理内存。特征是 _do_fork+xx/xxx pages=4 v malloc。

根据资料查询,在 kernel5.2 之后,该 meminfo 中实现了该统计项,可以使用下面命令获取 vmalloc 使用的物理内存大小:cat proc/meminfo | grep VmallocUsed

VmallocUsed:       73288 kB

4.1.2 Slab(slub)

Slab/Slob/Slub(统一简称 Slab)。slab 是 Linux 操作系统的一种内存分配机制。其工作是针对一些经常分配并释放的对象,如进程描述符等,这些对象的大小一般比较小,如果直接采用伙伴系统来进行分配和释放,不仅会造成大量的内存碎片,而且处理速度也太慢。而 slab 分配器是基于对象进行管理的,相同类型的对象归为一类(如进程描述符就是一类),每当要申请这样一个对象,slab 分配器就从一个 slab 列表中分配一个这样大小的单元出去,而当要释放时,将其重新保存在该列表中,而不是直接返回给伙伴系统,从而避免这些内碎片。slab 分配器并不丢弃已分配的对象,而是释放并把它们保存在内存中。当以后又要请求新的对象时,就可以从内存直接获取而不用重复初始化。内核常用接口如下: kmalloc(), kmalloc_node(), kmem_cache_alloc()。 Slab 中有两项统计NR_SLAB_RELACIMABLE 和 NR_SLAB_UNRECLAIMABLE ,在 kmem_getpages 时会加,在 kmem_freepages 时会减。在创建 slab 的时候,如果传入 flags 为 SLAB_RECLAIM_ACCOUNT,这个 kmem_cache 在分配时就将获得的页统计 NR_SLAB_RECLAIMABLE。获取命令:cat proc/slabinfo:

agn9190SYO_q6215:/ # cat proc/slabinfo
slabinfo - version: 2.1
# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
zs_handle          37376  37376      8  512    1 : tunables    0    0    0 : slabdata     73     73      0
f2fs_xattr_entry-259:69    312    312    208   39    2 : tunables    0    0    0 : slabdata      8      8      0
ext4_groupinfo_4k    196    196    144   28    1 : tunables    0    0    0 : slabdata      7      7      0
bio-3                288    288   3840    8    8 : tunables    0    0    0 : slabdata     36     36      0
dm_verity_fec_buffers     48     48   4048    8    8 : tunables    0    0    0 : slabdata      6      6      0
fscrypt_info           0      0    136   30    1 : tunables    0    0    0 : slabdata      0      0      0
UDPv6                184    184   1408   23    8 : tunables    0    0    0 : slabdata      8      8      0
tw_sock_TCPv6        132    132    248   33    2 : tunables    0    0    0 : slabdata      4      4      0
request_sock_TCPv6      0      0    312   26    2 : tunables    0    0    0 : slabdata      0      0      0
TCPv6                120    120   2176   15    8 : tunables    0    0    0 : slabdata      8      8      0
nf_conntrack_expect      0      0    224   36    2 : tunables    0    0    0 : slabdata      0      0      0
nf_conntrack         200    200    320   25    2 : tunables    0    0    0 : slabdata      8      8      0
ashmem_area_cache    234    234    312   26    2 : tunables    0    0    0 : slabdata      9      9      0
kcopyd_job             0      0   3312    9    8 : tunables    0    0    0 : slabdata      0      0      0
dm_uevent              0      0   2632   12    8 : tunables    0    0    0 : slabdata      0      0      0
cfq_io_cq            680    680    120   34    1 : tunables    0    0    0 : slabdata     20     20      0
f2fs_extent_tree    1785   1785     80   51    1 : tunables    0    0    0 : slabdata     35     35      0
f2fs_discard_cmd   57060  57060    112   36    1 : tunables    0    0    0 : slabdata   1585   1585      0
f2fs_discard_entry    690    874     88   46    1 : tunables    0    0    0 : slabdata     19     19      0
f2fs_free_nid       9350   9350     24  170    1 : tunables    0    0    0 : slabdata     55     55      0
f2fs_inode_cache    4460   4564   1168   28    8 : tunables    0    0    0 : slabdata    163    163      0
ovl_inode              0      0    704   23    4 : tunables    0    0    0 : slabdata      0      0      0
fuse_request         160    160    408   20    2 : tunables    0    0    0 : slabdata      8      8      0
fuse_inode           234    234    832   39    8 : tunables    0    0    0 : slabdata      6      6      0
exfat_inode_cache      0      0    768   21    4 : tunables    0    0    0 : slabdata      0      0      0
fat_inode_cache        0      0    760   21    4 : tunables    0    0    0 : slabdata      0      0      0
fat_cache              0      0     40  102    1 : tunables    0    0    0 : slabdata      0      0      0
jbd2_journal_handle    680    680     48   85    1 : tunables    0    0    0 : slabdata      8      8      0
jbd2_journal_head    170    170    120   34    1 : tunables    0    0    0 : slabdata      5      5      0
jbd2_revoke_table_s    512    512     16  256    1 : tunables    0    0    0 : slabdata      2      2      0
jbd2_revoke_record_s   5504   5504     32  128    1 : tunables    0    0    0 : slabdata     43     43      0
ext4_inode_cache    4437   4437   1104   29    8 : tunables    0    0    0 : slabdata    153    153      0
ext4_io_end         1088   1088     64   64    1 : tunables    0    0    0 : slabdata     17     17      0
mbcache              292    292     56   73    1 : tunables    0    0    0 : slabdata      4      4      0
kioctx                72     72    896   36    8 : tunables    0    0    0 : slabdata      2      2      0
dio                  200    200    640   25    4 : tunables    0    0    0 : slabdata      8      8      0
posix_timers_cache    680    680    240   34    2 : tunables    0    0    0 : slabdata     20     20      0
ip4-frags              0      0    216   37    2 : tunables    0    0    0 : slabdata      0      0      0
inet_peer_cache       63     63    192   21    1 : tunables    0    0    0 : slabdata      3      3      0
RAW                  272    272    960   34    8 : tunables    0    0    0 : slabdata      8      8      0
UDP                  991   1064   1152   28    8 : tunables    0    0    0 : slabdata     38     38      0
tw_sock_TCP            0      0    248   33    2 : tunables    0    0    0 : slabdata      0      0      0
request_sock_TCP       0      0    312   26    2 : tunables    0    0    0 : slabdata      0      0      0
TCP                   32     32   2048   16    8 : tunables    0    0    0 : slabdata      2      2      0
inotify_inode_mark    408    408     80   51    1 : tunables    0    0    0 : slabdata      8      8      0
dax_cache             78     78    832   39    8 : tunables    0    0    0 : slabdata      2      2      0
bio_fallback_crypt_ctx    144    144    112   36    1 : tunables    0    0    0 : slabdata      4      4      0
blk_crypto_decrypt_work   5202   5202     40  102    1 : tunables    0    0    0 : slabdata     51     51      0
request_queue        105    105   2072   15    8 : tunables    0    0    0 : slabdata      7      7      0
blkdev_ioc           741    741    104   39    1 : tunables    0    0    0 : slabdata     19     19      0
sock_inode_cache    1012   1012    704   23    4 : tunables    0    0    0 : slabdata     44     44      0
configfs_dir_cache    378    378     96   42    1 : tunables    0    0    0 : slabdata      9      9      0
file_lock_cache      160    160    200   20    1 : tunables    0    0    0 : slabdata      8      8      0
net_namespace          0      0   7168    4    8 : tunables    0    0    0 : slabdata      0      0      0
shmem_inode_cache   2162   2162    712   23    4 : tunables    0    0    0 : slabdata     94     94      0
taskstats            184    184    344   23    2 : tunables    0    0    0 : slabdata      8      8      0
proc_inode_cache    6694   7567    696   23    4 : tunables    0    0    0 : slabdata    329    329      0
sigqueue             200    200    160   25    1 : tunables    0    0    0 : slabdata      8      8      0
bdev_cache           288    288    896   36    8 : tunables    0    0    0 : slabdata      8      8      0
kernfs_node_cache  42240  42240    136   30    1 : tunables    0    0    0 : slabdata   1408   1408      0
mnt_cache           6622   6804    448   36    4 : tunables    0    0    0 : slabdata    189    189      0
filp               14081  14975    320   25    2 : tunables    0    0    0 : slabdata    599    599      0
inode_cache        29820  29926    624   26    4 : tunables    0    0    0 : slabdata   1151   1151      0
dentry             49833  51114    192   21    1 : tunables    0    0    0 : slabdata   2434   2434      0
iint_cache             0      0    120   34    1 : tunables    0    0    0 : slabdata      0      0      0
ebitmap_node        5568   5568     64   64    1 : tunables    0    0    0 : slabdata     87     87      0
avtab_node         40970  40970     24  170    1 : tunables    0    0    0 : slabdata    241    241      0
avc_xperms_data    13312  13312     32  128    1 : tunables    0    0    0 : slabdata    104    104      0
avc_node            6445   7168     72   56    1 : tunables    0    0    0 : slabdata    128    128      0
selinux_file_security  16640  16640     16  256    1 : tunables    0    0    0 : slabdata     65     65      0
selinux_inode_security  48231  50286     40  102    1 : tunables    0    0    0 : slabdata    493    493      0
buffer_head         3423   4290    104   39    1 : tunables    0    0    0 : slabdata    110    110      0
nsproxy             4161   4161     56   73    1 : tunables    0    0    0 : slabdata     57     57      0
vm_area_struct    143492 155696    216   37    2 : tunables    0    0    0 : slabdata   4208   4208      0
mm_struct            288    288    896   36    8 : tunables    0    0    0 : slabdata      8      8      0
files_cache          273    273    768   21    4 : tunables    0    0    0 : slabdata     13     13      0
signal_cache         672    672   1024   32    8 : tunables    0    0    0 : slabdata     21     21      0
sighand_cache        585    585   2112   15    8 : tunables    0    0    0 : slabdata     39     39      0
task_struct         2228   2728   3840    8    8 : tunables    0    0    0 : slabdata    341    341      0
cred_jar            1953   1953    192   21    1 : tunables    0    0    0 : slabdata     93     93      0
anon_vma_chain     92845  99776     64   64    1 : tunables    0    0    0 : slabdata   1559   1559      0
anon_vma           52117  55798     88   46    1 : tunables    0    0    0 : slabdata   1213   1213      0
pid                 3136   3136    128   32    1 : tunables    0    0    0 : slabdata     98     98      0
trace_event_file    2852   2852     88   46    1 : tunables    0    0    0 : slabdata     62     62      0
ftrace_event_field  10880  10880     48   85    1 : tunables    0    0    0 : slabdata    128    128      0
radix_tree_node    21476  21476    584   28    4 : tunables    0    0    0 : slabdata    767    767      0
task_group           168    168    384   21    2 : tunables    0    0    0 : slabdata      8      8      0
dma-kmalloc-8k         0      0   8192    4    8 : tunables    0    0    0 : slabdata      0      0      0
dma-kmalloc-4k         0      0   4096    8    8 : tunables    0    0    0 : slabdata      0      0      0
dma-kmalloc-2k         0      0   2048   16    8 : tunables    0    0    0 : slabdata      0      0      0
dma-kmalloc-1k         0      0   1024   32    8 : tunables    0    0    0 : slabdata      0      0      0
dma-kmalloc-512        0      0    512   32    4 : tunables    0    0    0 : slabdata      0      0      0
dma-kmalloc-256        0      0    256   32    2 : tunables    0    0    0 : slabdata      0      0      0
dma-kmalloc-128        0      0    128   32    1 : tunables    0    0    0 : slabdata      0      0      0
kmalloc-rcl-8k         0      0   8192    4    8 : tunables    0    0    0 : slabdata      0      0      0
kmalloc-rcl-4k         0      0   4096    8    8 : tunables    0    0    0 : slabdata      0      0      0
kmalloc-rcl-2k         0      0   2048   16    8 : tunables    0    0    0 : slabdata      0      0      0
kmalloc-rcl-1k         0      0   1024   32    8 : tunables    0    0    0 : slabdata      0      0      0
kmalloc-rcl-512        0      0    512   32    4 : tunables    0    0    0 : slabdata      0      0      0
kmalloc-rcl-256     1056   1056    256   32    2 : tunables    0    0    0 : slabdata     33     33      0
kmalloc-rcl-128     2336   2336    128   32    1 : tunables    0    0    0 : slabdata     73     73      0
kmalloc-8k           285    300   8192    4    8 : tunables    0    0    0 : slabdata     75     75      0
kmalloc-4k           904    920   4096    8    8 : tunables    0    0    0 : slabdata    115    115      0
kmalloc-2k          1168   1168   2048   16    8 : tunables    0    0    0 : slabdata     73     73      0
kmalloc-1k          3627   7040   1024   32    8 : tunables    0    0    0 : slabdata    220    220      0
kmalloc-512         5274   6048    512   32    4 : tunables    0    0    0 : slabdata    189    189      0
kmalloc-256        11453  12128    256   32    2 : tunables    0    0    0 : slabdata    379    379      0
kmalloc-128       150909 154560    128   32    1 : tunables    0    0    0 : slabdata   4830   4830      0
kmem_cache_node      192    192    128   32    1 : tunables    0    0    0 : slabdata      6      6      0
kmem_cache           168    168    384   21    2 : tunables    0    0    0 : slabdata      8      8      0

4.1.3 Kernel stack

所有 task 的 stack 占用的内存,包括 kernel thread 和 user space 进程包含的线程,在 eminfo 中有该统计项。在 CONFIG_VMAP_STACK 打开的工程中,该项和 vmalloc 的统计重复。获取命令:cat /proc/meminfo |grep KernelStack:

KernelStack:       34224 kB

4.1.4 Pagetables

所有用户进程的 PTE 表,没有包含 fork 时的 PGD 表申请的内存。在 meminfo 中有该统计项:cat /proc/meminfo | grep PageTables

agn9190SYO_q6215:/ # cat /proc/meminfo | grep PageTables
PageTables:        63492 kB

总结:Kernel 使用的内存通常是以上四项之和。至于 shmem 项,一般认为是用户进程的,Google 把 shmem 计算到 kernel Used memory 中目前是存有异议的。

4.2 Drivers

通常 drivers 申请内存调用 kmalloc()或 vmalloc()相关函数,这些项可归 kernel common 统计项中。对于驱动中直接调用 alloc_pages() 等直接从 buddy 系统拿内存,需另外统计,如 android 系统中 ZRAM, GPU, ION 模块。Google 设计的 memtrack 中 EGL track 是统计 ION 使用物理内存的,GLtrack 是统计 GPU 使用物理内存,这需要 vendor 厂商实现相关接口。目前只有 Rouge 系列 GPU 实现了相关的接口。

4.2.1 ZRAM 使用 mem 的信息

Zram 是使用内存实现的带压缩功能的块设备。其处理的对象是进程的匿名页,把匿名页压缩后借助 swap 重新放到内存中,其压缩比大约是 3 :1, 这样理论上能节省内存。

4.2.2 GPU 使用 mem 的信息

GPU 类型分两种一种是 arm 自带的 mali, 另一种

是 rogue 系列,如果实现了 memtack 相关的接口,可使用 memtrack 跟踪该部分内存到底是哪个进程使用。 此外也通过如下方式查看:

对于 mali 系列的 GPU:cat /sys/kernel/debug/mali0/gpu_memory

 cat gpu_memory
mali0                  11242
  kctx-0x000000009376adac        198
  kctx-0x000000005ed0f982        868
  kctx-0x000000006b76fdd5        869
  kctx-0x000000001f314c49       4741
  kctx-0x00000000e0382bd9         53
  kctx-0x00000000ef805d8b       4027
  kctx-0x00000000c5daf583        115
  kctx-0x00000000569b23ac        371

对于 Rouge 系列的 GPU:cat /sys/kernel/debug/pvr/memtrack_stats

4.2.3 ION(multi-media) 使用 mem 的信息

Ion 有多种内存分配 ion_heap,按照内存来源可以分为两类:平台预留 mem 和使用内核 buddy 系统管理的 mem。不了解这块的信息,只简单介绍下。

使用平台预留的 mem(比如 ION_HEAP_TYPE_CARVEOUT),统计在 memory reserved 项中, 通常用于 camera 等系统的调试。

使用内核 buddy 系统管理的 mem,比如 ION_HEAP_TYPE_SYSTEM 直接从 buddy 系统获取 page),ION_HEAP_TYPE_SYSTEM_CONTIG (直接从 buddy 系统获取指定大小的连续内存块)。



版权声明:本文为qq_29413633原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。