思维导图
数据来源
- /proc/meminfo 内存状态信息
- dumpsys meminfo 内存分解
内存分解对比项
一、硬件保留内存
保留内存 = 实际物理内存大小 - MemTotal
这块内存大小和驱动功能有关,需要BSP去排查每项功能内存分配,是否有裁剪的空间
MTK平台的保留内存拆机方法:reserved memory
二、MemFree剩余物理内存
影响因素:
- 进程的数量:对比当前进程数量是否相差较多,是否有不需要存在的进程
- kswapd内存回收水位:内存回收的激进程度是否一致,是否因水位过高,从而导致回收了更多的内存。通过/proc/zoninfo中每个内存扇区的min/low/high来确认
- dalvik的heap配置不一样,导致每个进程的内存存在差异,需要确认此配置的影响
三、MemAvailable剩余可用内存
可用内存大小和kernel内存占用,用户空间内存占用这两块有关,同时为了准确排查,需要去除zram的影响,最好能在关闭zram的情况下进行对比。
Kernel占用内存
kernel占用内存情况通过/proc/meminfo信息来获取,
kernel占用内存 = Shmem + SUnreclaim + KernelStack + PageTables + VmallocUsed
Shmem包括:
- shared memory
- SysV shared memory [shmget etc.]
- POSIX shared memory [shm_open etc.]
- shared anonymous mmap [ mmap(…MAP_ANONYMOUS|MAP_SHARED…)]
- tmpfs和devtmpfs
Sunreclaim:
查看/proc/slabinfo信息,查看分配内存较大的模块,差异较大的由对应模块分析。
KernelStack:
内核线程栈占用的空间。
每一个用户线程都会分配一个kernel stack(内核栈),内核栈虽然属于线程,但用户态的代码不能访问,只有通过系统调用(syscall)、自陷(trap)或异常(exception)进入内核态的时候才会用到,也就是说内核栈是给kernel code使用的。
Kernel stack(内核栈)是常驻内存的,既不包括在LRU lists里,也不包括在进程的RSS/PSS内存里。所以属于kernel消耗的内存。
PageTables:
进程页表所占用的内存。
用于将内存的虚拟地址翻译成物理地址。随着内存地址分配的越来越多,page table 会增大。和进程数量有关。
VmallocUsed:
查看/proc/vmallocinfo信息,查看每个功能模块使用的大小,差异较大的由对应模块分析。
用户空间占用内存
通过dumpsys meminfo获取"Total PSS by OOM adjustment"下每个进程占用的内存大小,对比内存大小超过5M的每个进程。
同时参照《内存参数建议标准》,
- 如果进程数量差异较大,确认lmkd的查杀程度,以及AMS的CUR_MAX_CACHED_PROCESSES配置是否一致
- 如果相同进程的内存差异较大,确认dalvik的heap参数是否一致