目录
1. adb shell cat /proc/meminfo
3. adb shell dumpsys meminfo [pid/serverName]
5. adb shell cat /proc/`pidof cameraserver`/smaps
6. adb shell showmap `pidof cameraserver`
1. adb shell cat /proc/meminfo
MemTotal: 877368 kB | 所有可用RAM大小(即物理内存减去一些预留位和内核的二进制代码大小)(HighTotal + LowTotal),系统从加电开始到引导完成,BIOS等要保留一些内存,内核要保留一些内存,最后剩下可供系统支配的内存就是MemTotal。这个值在系统运行期间一般是固定不变的。 |
MemFree: 22516 kB | LowFree 与 HighFree 的总和,被系统留着未使用的内存,MemFree是说的系统层面 |
MemAvailable: 470244 kB | 应用程序可用内存数。系统中有些内存虽然已被使用但是可以回收的,比如cache/buffer、slab都有一部分可以回收,所以MemFree不能代表全部可用的内存,这部分可回收的内存加上MemFree才是系统可用的内存,即:MemAvailable≈MemFree+Buffers+Cached,它是内核使用特定的算法计算出来的,是一个估计,MemAvailable是说的应用程序层面 |
Buffers: 1772 kB | 用来给文件做缓冲大小 |
Cached: 459224 kB | 被高速缓冲存储器(cache memory)用的内存的大小(等于 diskcache minus SwapCache ) |
SwapCached: 16 kB | 被高速缓冲存储器(cache memory)用的交换空间的大小,已经被交换出来的内存,但仍然被存放在swapfile中。用来在需要的时候很快的被替换而不需要再次打开I/O端口 |
Active: 333148 kB | 在活跃使用中的缓冲或高速缓冲存储器页面文件的大小,除非非常必要否则不会被移作他用. (Active(anon) + Active(file)) |
Inactive: 330384 kB | 在不经常使用中的缓冲或高速缓冲存储器页面文件的大小,可能被用于其他途径. (Inactive(anon) + Inactive(file)) |
Active(anon): 104368 kB | 活跃的与文件无关的内存(比如进程的堆栈,用malloc申请的内存)(anonymous pages),anonymous pages在发生换页时,是对交换区进行读/写操作 |
Inactive(anon): 104508 kB | 非活跃的与文件无关的内存(比如进程的堆栈,用malloc申请的内存) |
Active(file): 228780 kB | 活跃的与文件关联的内存(比如程序文件、数据文件所对应的内存页)(file-backed pages) File-backed pages在发生换页(page-in或page-out)时,是从它对应的文件读入或写出 |
Inactive(file): 225876 kB | 非活跃的与文件关联的内存(比如程序文件、数据文件所对应的内存页) |
Unevictable: 6708 kB | |
Mlocked: 1428 kB | |
HighTotal: 261888 kB | 高位内存总大小(Highmem是指所有内存高于860MB的物理内存,Highmem区域供用户程序使用,或用于页面缓存。该区域不是直接映射到内核空间。内核必须使用不同的手法使用该段内存) |
HighFree: 5680 kB | 未被使用的高位内存大小 |
LowTotal: 615480 kB | 低位内存总大小,低位可以达到高位内存一样的作用,而且它还能够被内核用来记录一些自己的数据结构 |
LowFree: 16836 kB | 未被使用的低位大小 |
SwapTotal: 614396 kB | 交换空间的总大小 |
SwapFree: 611044 kB | 未被使用交换空间的大小 |
Dirty: 40 kB | 等待被写回到磁盘的内存大小 |
Writeback: 0 kB | 正在被写回到磁盘的内存大小 |
AnonPages: 209224 kB | 未映射页的内存大小 |
Mapped: 280668 kB | 设备和文件等映射的大小 |
Shmem: 1084 kB | |
Slab: 59840 kB | 内核数据结构缓存的大小,可以减少申请和释放内存带来的消耗 |
SReclaimable: 34196 kB | 可收回Slab的大小 |
SUnreclaim: 25644 kB | 不可收回Slab的大小(SUnreclaim+SReclaimable=Slab) |
KernelStack: 7504 kB | 常驻内存,每一个用户线程都会分配一个kernel stack(内核栈) |
PageTables: 15508 kB | 管理内存分页页面的索引表的大小 |
NFS_Unstable: 0 kB | 不稳定页表的大小 |
Bounce: 0 kB | |
WritebackTmp: 0 kB | |
CommitLimit: 1053080 kB | 根据超额分配比率('vm.overcommit_ratio'),这是当前在系统上分配可用的内存总量,这个限制只是在模式2('vm.overcommit_memory')时启用。CommitLimit用以下公式计算:CommitLimit =('vm.overcommit_ratio'*物理内存)+交换例如,在具有1G物理RAM和7G swap的系统上,当`vm.overcommit_ratio` = 30时 CommitLimit =7.3G |
Committed_AS: 16368536 kB | 目前在系统上分配的内存量。是所有进程申请的内存的总和,即时所有申请的内存没有被完全使用,例如一个进程申请了1G内存,仅仅使用了300M,但是这1G内存的申请已经被 "committed"给了VM虚拟机,进程可以在任何时间使用。如果限制在模式2('vm.overcommit_memory')时启用,分配超出CommitLimit内存将不被允许 |
VmallocTotal: 245760 kB | 可以vmalloc虚拟内存大小 |
VmallocUsed: 0 kB | vmalloc已使用的虚拟内存大小 |
VmallocChunk: 0 kB | 最大的连续未被使用的vmalloc区域 |
2. adb shell dumpsys meminfo
2.1 相关名词解释(USS/PSS/RSS/VSS)
Item | 全称 | 含义 | 等价 |
USS | Unique Set Size | 物理内存 | 进程独占的内存 |
PSS | Proportional Set Size | 物理内存 | PSS= USS+ 按比例包含共享库 |
RSS | Resident Set Size | 物理内存 | RSS= USS+ 包含共享库 |
VSS | Virtual Set Size | 虚拟内存 | VSS= RSS+ 未分配实际物理内存 |
从以上打印可以看出,一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS
VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)是单个进程全部可访问的地址空间
RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)是单个进程实际占用的内存大小,对于单个共享库, 尽管无论多少个进程使用,实际该共享库只会被装入内存一次。
PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
USS - Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)USS 是一个非常非常有用的数字, 因为它揭示了运行一个特定进程的真实的内存增量大小。如果进程被终止, USS 就是实际被返还给系统的内存大小。USS 是针对某个进程开始有可疑内存泄露的情况,进行检测的最佳数字。怀疑某个程序有内存泄露可以查看这个值是否一直有增加。
2.2 内容排列规律
序列 | 划分类型 | 排序 | 解释 |
1 | process | PSS | 以进程的PSS从大到小依次排序显示,每行显示一个进程; |
2 | OOM adj | PSS | Native/System/Persistent/Foreground/Visible/Perceptible/A Services/Home/B Services/Cached,分别显示每类的进程情况 |
3 | category | PSS | 以Dalvik/Native/.art mmap/.dex map等划分的各类进程的总PSS情况 |
4 | total | – | 总内存、剩余内存、可用内存、其他内存 |
Total RAM: 7,799,192K (status normal)
Free RAM: 6,156,245K ( 646,177K cached pss + 5,113,752K cached kernel + 396,316K free)
ION: 371,164K ( 191,872K mapped + 48K unmapped + 179,244K pools)
Used RAM: 1,897,567K (1,309,179K used pss + 588,388K kernel)
Lost RAM: 198,954K
ZRAM: 141,216K physical used for 671,232K in swap (4,272,548K total swap)
Tuning: 256 (large 512), oom 322,560K, restore limit 107,520K (high-end-gfx)
3. adb shell dumpsys meminfo [pid/serverName]
dumsys meminfo 原理&应用(很棒!!!)
命令:
adb shell dumpsys meminfo `pidof cameraserver`
adb shell dumpsys meminfo cameraserver
Applications Memory Usage (in Kilobytes):
Uptime: 103775497 Realtime: 197947921
Pss Private Private SwapPss Rss Heap Heap Heap
Total Dirty Clean Dirty Total Size Alloc Free
------ ------ ------ ------ ------ ------ ------ ------
Native Heap 828 828 0 488 828 0 0 0
Dalvik Heap 0 0 0 0 0 0 0 0
Stack 120 120 0 92 120
Ashmem 130 0 0 0 284
Other dev 12 0 12 0 352
.so mmap 6505 2336 2820 0 15384
Other mmap 49 28 0 0 504
EGL mtrack 9957 9957 0 0 9957
Unknown 80 80 0 404 80
TOTAL 18665 13349 2832 984 18665 0 0 0
App Summary
Pss(KB) Rss(KB)
------ ------
Java Heap: 0 0
Native Heap: 828 828
Code: 5156 15384
Stack: 120 120
Graphics: 9957 9957
Private Other: 120
System: 2484
Unknown: 1220
TOTAL PSS: 18665 TOTAL RSS: 27509 TOTAL SWAP PSS: 984
4. adb shell free
free 命令中的信息都来自于 cat /proc/meminfo
Linux free 命令详解(含sawp的解释)
adb shell free -h
total used free shared buffers
Mem: 7.4G 7.2G 233M 13M 1.9M
-/+ buffers/cache: 7.2G 235M
Swap: 4.0G 622M 3.4G
5. adb shell cat /proc/`pidof cameraserver`/smaps
cat /proc/`pidof cameraserver`/smaps命令详解(各个字段含义)
命令:adb shell cat /proc/`pidof cameraserver`/smaps
01767000-01768000 r--p 00000000 fd:04 1306 /system/bin/cameraserver
Size: 4 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 4 kB
Pss: 2 kB
Shared_Clean: 4 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
Referenced: 4 kB
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
Locked: 0 kB
VmFlags: rd mr mw me dw
01768000-01769000 r-xp 00000000 fd:04 1306 /system/bin/cameraserver
Size: 4 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 4 kB
Pss: 2 kB
Shared_Clean: 4 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
Referenced: 4 kB
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
Locked: 0 kB
VmFlags: rd ex mr mw me dw
01769000-0176a000 r--p 00000000 fd:04 1306 /system/bin/cameraserver
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
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
Locked: 0 kB
VmFlags: rd mr mw me dw ac
6. adb shell showmap `pidof cameraserver`
showmap实际上是读取/proc/pid/smap 文件,源码如下
Cross Reference: /system/extras/showmap/showmap.cpp (androidxref.com)
173static mapinfo *load_maps(int pid, int sort_by_address, int coalesce_by_name) 174{ 175 char fn[128]; 176 FILE *fp; 177 char line[1024]; 178 mapinfo *head = NULL; 179 mapinfo *current = NULL; 180 int len; 181 182 snprintf(fn, sizeof(fn), "/proc/%d/smaps", pid); 183 fp = fopen(fn, "r"); 184 if (fp == 0) { 185 if (!quiet) fprintf(stderr, "cannot open /proc/%d/smaps: %s\n", pid, strerror(errno)); 186 return NULL; 187 } 188 189 while (fgets(line, sizeof(line), fp) != 0) { 190 len = strlen(line); 191 if (line[len - 1] == '\n') { 192 line[--len] = 0; 193 } 194 195 if (current != NULL && !parse_field(current, line)) { 196 continue; 197 } 198 199 mapinfo *next; 200 if (!parse_header(line, current, &next)) { 201 enqueue_map(&head, current, sort_by_address, coalesce_by_name); 202 current = next; 203 continue; 204 } 205 206 fprintf(stderr, "warning: could not parse map info line: %s\n", line); 207 } 208 209 enqueue_map(&head, current, sort_by_address, coalesce_by_name); 210 211 fclose(fp); 212 213 if (!head) { 214 if (!quiet) fprintf(stderr, "could not read /proc/%d/smaps\n", pid); 215 return NULL; 216 } 217 218 return head; 219}
showmap [-t] [-v] [-c] [-q]
-t = terse (show only items with private pages)
-v = verbose (don't coalesce maps with the same name)
-a = addresses (show virtual memory map)
-q = quiet (don't show error if map could not be read)
Ex. adb shell showmap `pidof cameraserver`
virtual shared shared private private
size RSS PSS clean dirty clean dirty swap swapPSS # object
-------- -------- -------- -------- -------- -------- -------- -------- -------- ---- ------------------------------
152 152 38 140 0 0 12 0 0 4 /apex/com.android.art/lib/libandroidicu.so
1720 592 153 548 0 0 44 0 0 4 /apex/com.android.art/lib/libicui18n.so
1252 292 100 240 0 0 52 0 0 4 /apex/com.android.art/lib/libicuuc.so
......(省略中间内容)
24 12 8 4 0 0 8 0 0 4 /system/lib/libstagefright_omx_utils.so
80 36 12 28 0 0 8 0 0 4 /system/lib/libstagefright_xmlparser.so
-------- -------- -------- -------- -------- -------- -------- -------- -------- ---- ------------------------------
virtual shared shared private private
size RSS PSS clean dirty clean dirty swap swapPSS # object
-------- -------- -------- -------- -------- -------- -------- -------- -------- ---- ------------------------------
53780 18876 7548 13128 332 2940 2476 856 856 683 TOTAL
注:我们一般只关注内存占用的话,只关注PSS+swapPSS(一般该项相对较小,因此不关注)这一列
如何比较两份showmap的内容(比较相同object的PSS值),如下图sheet A,B分别存放着两份showmap信息(去除不用关注的信息)
公式=B3-IFERROR(VLOOKUP(A3,A!$A$3:$C$869,2,FALSE),0)
比较出是那个库导致的查以后,然后用adb shell "showmap `pidof cameraserver` -v" 抓showmap,看看是某个库哪一部分导致(如下图),然后再review,这样就会找到怀疑的方向
virtual shared shared private private
size RSS PSS clean dirty clean dirty swap swapPSS flags object
-------- -------- -------- -------- -------- -------- -------- -------- -------- ------ ------------------------------
68 64 0 64 0 0 0 0 0 r-- /apex/com.android.runtime/lib64/bionic/libm.so
144 140 14 140 0 0 0 0 0 r-x /apex/com.android.runtime/lib64/bionic/libm.so
4 4 4 0 0 0 4 0 0 r-- /apex/com.android.runtime/lib64/bionic/libm.so
4 4 4 0 0 0 4 0 0 rw- /apex/com.android.runtime/lib64/bionic/libm.so
7. adb shell procrank
#adb shell procrank
PID Vss Rss Pss Uss Swap PSwap USwap ZSwap cmdline
1007 17323292K 253416K 98457K 81064K 62948K 42797K 41832K 10495K system_server
769 59532K 22640K 9503K 6972K 416K 416K 416K 102K /system/bin/cameraserver
5634 10777872K 7980K 5573K 5540K 0K 0K 0K 0K procrank
450 10776520K 5992K 1239K 1036K 820K 820K 820K 201K /system/bin/hwservicemanager
......
------ ------ ------ ------ ------ ------ ------
996040K 722256K 960812K 329867K 274948K 80897K TOTAL
ZRAM: 91680K physical used for 374272K in swap (4272548K total swap)
RAM: 7799192K total, 4838376K free, 6236K buffers, 1198096K cached, 8380K shmem, 168188K slab