Memory 知识介绍
目录
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 分三部分:
-
Kernel data & code
Kernel image 中不含已经释放的 init 段最终 reserved 的 memory,通常通过 proc/iomem 来查看。
cat proc/iomem | grep Kernel
80080000-8103ffff : Kernel code 81490000-81939fff : Kernel data
-
Kernel PageStruct
这是物理内存的管理成本;物理内存是通过分页机制进行管理,通常物理页的大小是 4K。kmemmap reserved 的 memory 管理所有 DDR 中的物理页的数据结构( struct page) ;在 flat 和 sparse 内存模型中其大小计算方法相同如下:Ddrsize / 4K * sizeof(Struct page)。
-
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 使用内存
进程使用内存,又分为两大类:(这两大类都会在进程地址空间中得到体现)
-
常规内存
:指的是某进程进行匿名映射,或者文件映射,或者读写文件 的缓存,或者普通 malloc,free 等等常规使用和运行时用到的 mem。可以看内核函数 vm_normal_page 的实现和注释。 -
特殊内存
:一些特殊的,使用物理内存直接 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)
-
Total RAM,同上述的 MemTotal。
-
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)
-
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)
-
Lost RAM:Lost RAM = Total RAM – Free RAM – Used RAM。具体这些内存谁使用??应该是内核模块在使用,模块可能是 zram,可以能 GPU,可能是 ION,可能是其它内核模块,这个值有时会得到是负数,是因为这套统计机制是有缺陷的。
-
ZRAM:zram 模块使用多少物理内存,存储了多少压缩后的 swap 内 存页,整个 swap 分区有多大。 但是上述 Free RAM 和 Used RAM 的算法是有些问题的,有计算重复的 地方。Cached PSS 应该是指所有处于 cached 的 adj 的 APP 的 PSS,而这些 PSS 是包括了文件映射 page 的,这样部分就和 cached 重复了。Cached 的 mem 应该有些也不会体现在 PSS 里面,比如没有人使用了,但是还没有回收 的那些(这些要研读 dumpsys meminfo 的代码实现才能最终确认)。
-
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 系统获取指定大小的连续内存块)。