Android常用内存分析命令
1.procrank
获取所有进程的内存使用的排行榜,按PSS排序
2.free
查看可用内存,单位KB
3.cat /proc/meminfo
查看系统整体内存情况,内存项按类型分类
MemAvailable ≈ MemFree+Buffers+Cached
每个进程的kernel stack 是16K,根据这个可以判断后台进程数
- MemAvailable = free - kernel reserved memory + ative file + inactive file + SReclaimable - 2 * zone low water mark
- Cached = All file page - buffers - swapping = Active file + Inactive file + Unevictable file - Buffers
- Slab = SReclaimable + SUnreclaimable
- Active = Active(anon) + Active(file)
- Inactive = Inactive(anon) + Inactive(file)
- AnonPages + Buffers + Cached = Active + Inactive
- Buffers + Cached = Active(file) + Inactive(file)
- SwapTotal = SwapFree + SwapUsed(Not SwapCached)
- KernelStack = the number of kernel task * Stack Size(16K)
- Kernel Memory Usage = KernelStack + USlab + PageTables + Shmem + Vmalloc
- Native Memory Usage = Mapped + AnonPages + Others
dumpsys meminfo
打印整体所有进程的内存使用,详细每个指标介绍写在《内存使用情况与监测》中dumpsys meminfo [pid | packageName]
针对具体进程or包名指行dump操作
6.cat /proc/pid/oom_score_adj
查看进程内存查杀优先级,-1000~1000范围,系统进程-1000,前台进程0,cache在900后
7.sys/module/lowmemorykiller/parameters/minfree
sys/module/lowmemorykiller/parameters/adj
旧版本lowmemorykiller使用的水位,Android R以后可以使用getprop |grep minfree查看
8.tombstone可以看虚拟内存的map
9.红屏异常等看SYSTEM_MEM_LOG 确认是否内存泄漏
10.cat /sys/kernel/debug/page_owner
- cat sys/kernel/slab/kmalloc-128
12.内核也提供了接口给用户触发规整动作,接口如下:/proc/sys/vm/compact_memory
只要往这个节点写值即可触发对系统所有node管理的内存做内存规整。
13.查看安卓后台cache 应用,一般8G设置为64,12G设置为128,6G设置为32,4G设置为16或者8
dumpsys activity settings |grep CUR_MAX_CACHED_PROCESSES
14.内核内存申请失败or超时log
查看kernel log打印:page allocation stalls for xxx ms 一般超过1s都是比较严重了
-
event.log 中搜索am_pss可以看各进程占用,搜索killinfo可以查看lmkd查杀进程信息
看log发现申请内存时order = 2的大小(也就是16KB),但buddy system 16KB的内存池只有:19*16kB (H)
其中的标志H表示这是highatomic的,禁止偷页。只有传进来的gfp_mask带有GFP_ATOMIC才能申请reserve的内存,所以发生了kernel OOM。
这题明显是内存碎片化。
dumpsys activity lmk 统计lmk打印
dumpsys meminfo 中的lostram统计
long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss) - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
18.DDR实时频率(虽然没啥用)
cat /sys/kernel/debug/clk/measure_only_mccc_clk/clk_measure
cat /proc/pagetypeinfo 查看当前buddy信息
(blocksize 和CONFIG_HUGETLB_PAGE有关,打开为2M,关闭为4M )cat /proc/zoneinfo 查看当前zone信息
zoneinfo_show_print -> node_page_state 读pglist_data的vm_stat计数器
spanned 2095616 内存管理区包含的页面
present 1980484 内存管理区实际管理的页面
managed 1921719 内存管理区被buddy管理的页面
protection: (0, 0) 预留的内存
node_unreclaimable: 0 页面回收失败次数
start_pfn: 525824 内存管理区的起始页帧号
- cat /proc/$pid/status |grep -E 'Name|Pid|Vm|Rss|Vm|Hu'
进程相关的内存信息
#include<linux/mm_type.h>
enum {
MM_FILEPAGES, /* Resident file mapping pages */
MM_ANONPAGES, /* Resident anonymous pages */
MM_SWAPENTS, /* Anonymous swap entries */
MM_SHMEMPAGES, /* Resident shared memory pages */
MM_UNRECLAIMABLE, /* Unreclaimable pages, e.g. shared with HW */
NR_MM_COUNTERS
};
- /proc/sys/vm 目录下均是调优参数
定义在kernel/sysctl.c中,通过proc文件系统实现
static struct ctl_table vm_table[] = {
{
.procname = "overcommit_memory",
.data = &sysctl_overcommit_memory, //传递的参数,通常是某个全局变量
.maxlen = sizeof(sysctl_overcommit_memory), //data的长度
.mode = 0644, //节点的文件权限,用户可读写,其他只读
.proc_handler = proc_dointvec_minmax, //节点在内核中的回调函数
.extra1 = &zreo, //这个参数的最小值
.extra1 = &two, //这个参数的最大值
},
...
}
- /proc/iomem 也提供了有关物理内存划分出的各个段的一些信息。
wolfgang@meitner> cat /proc/iomem
00000000-0009e7ff : System RAM
0009e800-0009ffff : reserved
000a0000-000bffff : Video RAM area
000c0000-000c7fff : Video ROM
000f0000-000fffff : System ROM
00100000-17ceffff : System RAM
00100000-00381ecc : Kernel code
00381ecd-004704df : Kernel data