- free
- cat procmeminfo
- VmallocUsed
- Slab
- echo m procsysrq-trigger
- Show process memory
- dumpsys meminfo pid cmdline
- dumpsys procstats
- procrank
- showmap or procmem
- summary
android系统上查看内存使用信息的命令,大概有以下几种。
1. free
2. cat /proc/meminfo
3. echo m > /proc/sysrq-trigger
4. dumpsys meminfo
5. dumpsys procstats
6. procrank
7. procmem
8. Showmap
free
p212:/ # free
total used free shared buffers
Mem: 1819103232 1318227968 500875264 0 11096064
-/+ buffers/cache: 1307131904 511971328
Swap: 524283904 0 524283904
Free命令输出的内存状态信息,一共有四行,第一行是title。第二行是从内核的角度来看的,第三行是从应用层的角度来看的。
上面的例子中:从OS的角度来看,一共有:1819103232KB(缺省时free的单位为KB)物理内存;在这些物理内存中有1318227968KB被使用了;还有500875264KB是可用的。
第三行:
-buffers/cache,表示应用程序认为系统被用掉多少内存;
+buffers/cache,表示应用程序认为系统还有多少内存;
第四行为swap区的信息,分别是swap的total,used和free。
buffers是用来缓冲块设备做的,它只记录文件系统的元数据(metadata)以及 tracking in-flight pages,而cached是用来给文件做缓冲。更通俗一点说:buffers主要用来存放目录里面有什么内容,文件的属性以及权限等等。而cached用来记忆我们打开过的文件和程序。
Free 的输出项与/proc/meminfo中的对应关系如下表所示:
free output | corresponding /proc/meminfo fields |
Mem: total | MemTotal |
Mem: used | MemTotal - MemFree |
Mem: free | MemFree |
Mem: shared (ignored now.) | N/A |
Mem: buffers | Buffers |
Mem: cached | Cached |
-/+ buffers/cache: used | MemTotal - (MemFree + Buffers + Cached) |
-/+ buffers/cache: free | MemFree + Buffers + Cached |
Swap: total | SwapTotal |
Swap: used | SwapTotal - SwapFree |
Swap: free | SwapFree |
cat /proc/meminfo
Source file: fs/proc/meminfo.c
以下主要来自以下内核文档
(Documentation/filesystems/proc.txt and Documentation/vm/hugetlbpage.txt)
- MemTotal: 总内存
- MemFree: free部分
- Buffers: buffer cache, 通常存放disk blocks(主要是metadata). 这部分不应该太大
- Cached: pagecache (Disk cache and Shared Memory)
- SwapCached: 在内存同时也在swapfile的memory。(如果系统需要这部分内存时,不需要重新swapped因为它已经在swappfile里了。内存紧张时,这可以减少io提高性能。)
- Active(anon): 最近使用并且通常不会swapp出去的匿名内存
- Inactive(anon): 非最过使用并且可以swapp出去的匿名内存
- Active(file): 最近使用的并且通常(除非必要)不会回收的Pagecache memory
- Inactive(file): 非最近使用可以回收的Pagecache memory
- Unevictable: Unevictable pages 不能swapped 出去
- Mlocked: 通过mlocked()系统调用locked 的 Pages, Mlocked locked pages也是Unevictable
- SwapTotal: 总的swap大小
- SwapFree: 空闲的swap空
- Dirty: 等待回写到disk的内存
- Writeback: 正在写回disk 的Memory
- AnonPages: mapped到用户空间的匿名内存,Active(anon)+Inactive(anon)
- Mapped: maaped的files,比如so等
- Slab: In-kernel data structures cache
- PageTables: 页表.
- VmallocTotal: vmalloc空间的总大小
- VmallocUsed: 使用的vmalloc
- VmallocChunk: 空闲的大块连续的vmalloc空间l
- Shmem: 共享内存
- SReclaimable: 可回收的slab
- SUnreclaim: 不可回收的slab
- KernelStack: kernel stack, 不可回收
VmallocUsed
VmallocUsed 并不完全对应物理内存,kernel有如下proc节点:cat /proc/vmallocinfo 可以查看具体的信息,其中列出了vmarea的大小,以及调用者和调用类型。
从调用类型来看,共有以下几种类型:
1) 来自ioremap,主要用来映射已经存在的寄存器、或者预先reserved内存,并不分配新的内存
0x0000000000000000-0x0000000000000000 8192 of_iomap+0x4c/0x68 ioremap
0x0000000000000000-0x0000000000000000 8192 persistent_ram_new+0x160/0x440 ioremap
2) 来自vmalloc,它会分配新的内存给调用者,可以看到 pages=xxx的打印,表示实际分配的page数量:
0x0000000000000000-0x0000000000000000 49152 jffs2_zlib_init+0x3c/0x80 pages=11 vmalloc
3) 来自vmap,vmap映射的page需要预先分配好,size是显示的area大小减去一个gap page。
0x0000000000000000-0x0000000000000000 8192 __dma_alloc_noncoherent+0xfc/0x228 vmap
vmap目前看起来主要来源是kernel公共部分的CMA内存。
Slab
Slab 有如下proc 节点 cat /proc/slabinfo可以查看,具体的slab内存使用情况。
这些item可以分成四大类:kernel使用的;空闲的;用户进程使用的和unknown。
- 用户进程使用的PSS = AnonPages + mapped
- 空闲的 = free + cached - mapped
- Kernel 使用的 = buffers + slab + page_tables + kernel stacks + shmem
- 剩余的就是 Unknown的(total 减去上面3部分的)。
Android系统中,unknown这部分包括vmalloc, ion内存,gpu使用的内存,各种driver使用的内存和其它的。
echo m > /proc/sysrq-trigger
Sysrq trigger show memory如下所示,开头部分是per-cpu memory信息;最后是swap信息。其中free按order和类型给出。
[10501.257140@3] SysRq : Show Memory
[10501.257341@0] Mem-Info:
[10501.257446@0] Normal per-cpu:
[10501.260275@0] CPU 0: hi: 186, btch: 31 usd: 24
[10501.265188@0] CPU 1: hi: 186, btch: 31 usd: 173
[10501.270103@0] CPU 2: hi: 186, btch: 31 usd: 83
[10501.275019@0] CPU 3: hi: 186, btch: 31 usd: 43
[10501.280042@0] active_anon:48564 inactive_anon:97 isolated_anon:0
[10501.280042@0] active_file:80726 inactive_file:134513 isolated_file:0
[10501.280042@0] unevictable:63 dirty:0 writeback:0 unstable:0
[10501.280042@0] free:122514 slab_reclaimable:5433 slab_unreclaimable:6756
[10501.280042@0] mapped:48040 shmem:177 pagetables:3382 bounce:0 used_cma:1099
[10501.280042@0] cma:0 anon_cma:11269 file_cma:79729 isolate_cma:0
[10501.280042@0] isolate:0
[10501.280042@0] unmovable:3914 reclaimable:651 movable:117949 reserve:0
[10501.326560@0] Normal free:490056kB min:5328kB low:28084kB high:29416kB active_anon:194256kB inactive_anon:388kB active_file:322904kB inactive_file:538052kB unevictable:252kB isolated(anon):0kB isolated(file):0kB present:2059264kB managed:1776468kB mlocked:252kB dirty:0kB writeback:0kB mapped:192160kB shmem:708kB slab_reclaimable:21732kB slab_unreclaimable:27024kB kernel_stack:9264kB pagetables:13528kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no
[10501.369716@0] lowmem_reserve[]: 0 0
[10501.373157@0] Normal: 166*4kB (UEM) 278*8kB (UEM) 318*16kB (UEM) 233*32kB (UEM) 66*64kB (UM) 29*128kB (UEM) 17*256kB (UEM) 1*512kB (U) 1*1024kB (U) 3*2048kB (UEM) 111*4096kB (M) = 490056kB
[10501.389828@0] Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
[10501.398345@0] 215411 total pagecache pages
[10501.402408@0] 0 pages in swap cache
[10501.405858@0] Swap cache stats: add 0, delete 0, find 0/0
[10501.411200@0] Free swap = 511996kB
[10501.414646@0] Total swap = 511996kB
[10501.418097@0] 514816 pages RAM
[10501.421113@0] 0 pages HighMem/MovableOnly
[10501.425079@0] 70699 pages reserved
Show process memory
- Vss(virtual set size): 指的是进程可以访问的虚拟地址空间大小,包括已经分配的但是没有驻留在 RAM 的内存。
- Rss(resident set size): 可以理解为共享内存+私有内存。
- Pss(Propotional set size):私有内存+平分的共享内存
- Uss((Unique set size): 私有内存。
dumpsys meminfo [pid | cmdline]
p212:/ # dumpsys meminfo com.android.systemui
Applications Memory Usage (in Kilobytes):
Uptime: 11656430 Realtime: 11656430
** MEMINFO in pid 4499 [com.android.systemui] **
Pss Private Private Swap Heap Heap Heap
Total Dirty Clean Dirty Size Alloc Free
------ ------ ------ ------ ------ ------ ------
Native Heap 2560 2428 0 0 8192 5009 3182
Dalvik Heap 2472 2324 0 0 4859 2916 1943
Dalvik Other 856 852 0 0
Stack 236 236 0 0
Ashmem 100 96 0 0
Other dev 4 0 4 0
.so mmap 1010 112 4 0
.apk mmap 1882 0 1540 0
.dex mmap 3848 4 3844 0
.oat mmap 2843 0 572 0
.art mmap 1459 724 12 0
Other mmap 9 4 0 0
Unknown 691 684 0 0
TOTAL 17970 7464 5976 0 13051 7925 5125
App Summary
Pss(KB)
------
Java Heap: 3060
Native Heap: 2428
Code: 6076
Stack: 236
Graphics: 0
Private Other: 1640
System: 4530
TOTAL: 17970 TOTAL SWAP (KB): 0
Objects
Views: 102 ViewRootImpl: 1
AppContexts: 3 Activities: 0
Assets: 2 AssetManagers: 2
Local Binders: 57 Proxy Binders: 31
Parcel memory: 7 Parcel count: 28
Death Recipients: 0 OpenSSL Sockets: 0
WebViews: 0
SQL
MEMORY_USED: 0
PAGECACHE_OVERFLOW: 0 MALLOC_SIZE: 0
即可以统计系统的内存使用情况,也可以按类别输出具体进程的内存统计信息。分类非常详细。
dumpsys procstats
p212:/ # dumpsys procstats
* com.android.deskclock / u0a29 / v450:
TOTAL: 16% (27MB-27MB-27MB/22MB-22MB-22MB over 1)
Imp Fg: 16% (27MB-27MB-27MB/22MB-22MB-22MB over 1)
(Cached): 84% (13MB-13MB-13MB/8.7MB-8.7MB-8.7MB over 1)
…
Memory usage:
Kernel : 83MB (16 samples)
Native : 157MB (16 samples)
Persist: 86MB (25 samples)
Top : 67MB (11 samples)
ImpFg : 21MB (12 samples)
Service: 17MB (12 samples)
CchEmty: 44MB (33 samples)
Cached : 654MB (16 samples)
Free : 477MB (16 samples)
Z-Ram : 12KB (16 samples)
TOTAL : 1.6GB
ServRst: 338KB (3 samples)
Start time: 2015-01-01 03:01:08
Total elapsed time: +18m47s347ms (partial) libart.so
这个命令可以给出进程内存使用的变化,但是缺点是没有native进程。
procrank
p212:/ # procrank
PID Vss Rss Pss Uss cmdline
4332 2294072K 112688K 64222K 56212K system_server
4050 1548540K 63584K 30934K 19304K zygote
4049 2109624K 72984K 24981K 16652K zygote64
4499 1565212K 61576K 18108K 13444K com.android.systemui
13589 994028K 42332K 15576K 7820K com.android.bluetooth
13621 32032K 14232K 13321K 13288K procrank
1572 1544068K 57064K 13157K 8232K com.android.deskclock
5121 1539228K 55172K 12695K 8576K android.process.media
…
5292 1555008K 48336K 8127K 4652K com.android.launcher
…
3961 10148K 1940K 382K 68K /system/bin/debuggerd64
3960 5348K 1600K 367K 72K /system/bin/debuggerd
3963 9892K 652K 304K 56K debuggerd64:signaller
3965 5092K 516K 246K 56K debuggerd:signaller
------ ------ ------
407191K 293724K TOTAL
可以输出各个进程使用的内存情况,VSS, PSS, RSS等。
showmap or procmem
可以得到更细致的内存使用信息。
summary
所有这些查看进程内存使用信息的工具,都是读取进程的smaps文件做的统计。下面是截取的smaps中的一段,RSS, PSS 等信息非常详细。
7ffd510fb000-7ffd5121c000 rw-p 00000000 00:00 0 [stack]
Size: 2180 kB
Rss: 16 kB
Pss: 16 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 16 kB
Referenced: 12 kB
Anonymous: 16 kB
AnonHugePages: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
VmFlags: rd wr mr mw me gd ac