一、概述
1.1 內(nèi)存指標概念
Item
全稱
含義
等價
USSUnique Set Size物理內(nèi)存進程獨占的內(nèi)存
PSSProportional Set Size物理內(nèi)存PSS= USS+ 按比例包含共享庫
RSSResident Set Size物理內(nèi)存RSS= USS+ 包含共享庫
VSSVirtual Set Size虛擬內(nèi)存VSS= RSS+ 未分配實際物理內(nèi)存
故內(nèi)存的大小關(guān)系:VSS >= RSS >= PSS >= USS
1.2 內(nèi)存分析命令
常用的內(nèi)存調(diào)優(yōu)分析命令:
dumpsys meminfo
procrank
cat /proc/meminfo
free
showmap
vmstat
二 命令說明
1. dumpsys meminfo
dumpsys meminfo命令的輸出結(jié)果分以下4部分:
序列
劃分類型
排序
解釋
1processPSS以進程的PSS從大到小依次排序顯示关面,每行顯示一個進程诫给;
2OOM adjPSSNative/System/Persistent/Foreground/Visible/Perceptible/A Services/Home/B Services/Cached,分別顯示每類的進程情況
3categoryPSS以Dalvik/Native/.art mmap/.dex map等劃分的各類進程的總PSS情況
4total–總內(nèi)存陋桂、剩余內(nèi)存岁歉、可用內(nèi)存术羔、其他內(nèi)存
命令內(nèi)容:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52TotalPSSbyprocess://以process來劃分
167128kB:com.android.systemui(pid4395)
124527kB:system(pid1192)
44213kB:com.android.settings(pid29256/activities)
41822kB:surfaceflinger(pid391)
...
TotalPSSbyOOMadjustment://以oom來劃分杨箭,會詳細列舉所有的類別的進程寞焙,此處省略.
183683kB:Native
42024kB:surfaceflinger(pid388)
16740kB:mediaserver(pid471)
16040kB:zygote(pid494)
...
124527kB:System
344259kB:Persistent
69719kB:Foreground
49026kB:Visible
34005kB:Perceptible
7880kB:AServices
58689kB:Home
98352kB:BServices
94888kB:Cached
TotalPSSbycategory:// 以category劃分
309449kB:Dalvik
230330kB:Native
145344kB:EGLmtrack
117797kB:.sommap
54389kB:.artmmap
44886kB:.dexmmap
32428kB:DalvikOther
31083kB:.oatmmap
29456kB:Stack
21782kB:Gfxdev
21733kB:Unknown
12695kB:.apkmmap
9367kB:Othermmap
2169kB:.ttfmmap
2062kB:Otherdev
38kB:.jarmmap
12kB:Ashmem
8kB:Cursor
0kB:GLmtrack
0kB:Othermtrack
//整體情況
TotalRAM:2857032kB(statusmoderate)
FreeRAM:1439488kB(94888cachedpss+344620cachedkernel+999980free)
UsedRAM:1280552kB(970140usedpss+310412kernel)
LostRAM:136992kB
ZRAM:4kBphysicalusedfor0kBinswap(524284kBtotalswap)
Tuning:256(large512),oom525000kB,restorelimit175000kB(high-end-gfx)
另外,可只輸出某個pid或package的進程信息:
Java
1
2dumpsysmeminfo// 輸出指定pid的某一進程
dumpsysmeminfo--package// 輸出指定包名的進程互婿,可能包含多個進程
2. procrank
功能: 獲取所有進程的內(nèi)存使用的排行榜捣郊,排行是以Pss的大小而排序。procrank命令比dumpsys meminfo命令慈参,能輸出更詳細的VSS/RSS/PSS/USS內(nèi)存指標呛牲。
最后一行輸出下面6個指標:
totalfreebufferscachedshmemslab
執(zhí)行結(jié)果:
Java
1
2
3
4
5
6
7
8
9
10
11root@Phone:/#procrank
PIDVssRssPssUsscmdline
43952270020K202312K136099K121964Kcom.android.systemui
11922280404K147048K89883K84144Ksystem_server
292562145676K97880K44328K40676Kcom.android.settings
5011458332K61876K23609K9736Kzygote
42392105784K68056K21665K19592Kcom.android.phone
479164392K24068K17970K15364K/system/bin/mediaserver
391200892K27272K15930K11664K/system/bin/surfaceflinger
...
RAM:2857032Ktotal,998088Kfree,78060Kbuffers,459780Kcached,312Kshmem,92392Kslab
3. cat /proc/meminfo
功能:能否查看更加詳細的內(nèi)存信息
Java
1
指令:cat/proc/meminfo
輸出結(jié)果如下(結(jié)果內(nèi)存值不帶小數(shù)點,此處添加小數(shù)點的目的是為了便于比對大小):
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41root@phone:/#cat/proc/meminfo
MemTotal:2857.032kB//RAM可用的總大小 (即物理總內(nèi)存減去系統(tǒng)預留和內(nèi)核二進制代碼大小)
MemFree:1020.708kB//RAM未使用的大小
Buffers:75.104kB//用于文件緩沖
Cached:448.244kB//用于高速緩存
SwapCached:0kB//用于swap緩存
Active:832.900kB//活躍使用狀態(tài)驮配,記錄最近使用過的內(nèi)存娘扩,通常不回收用于其它目的
Inactive:391.128kB//非活躍使用狀態(tài),記錄最近并沒有使用過的內(nèi)存僧凤,能夠被回收用于其他目的
Active(anon):700.744kB//Active = Active(anon) + Active(file)
Inactive(anon):228kB//Inactive = Inactive(anon) + Inactive(file)
Active(file):132.156kB
Inactive(file):390.900kB
Unevictable:0kB
Mlocked:0kB
SwapTotal:524.284kB//swap總大小
SwapFree:524.284kB//swap可用大小
Dirty:0kB//等待往磁盤回寫的大小
Writeback:0kB//正在往磁盤回寫的大小
AnonPages:700.700kB
Mapped:187.096kB//通過mmap()分配的內(nèi)存畜侦,用于map設備元扔、文件或者庫
Shmem:.312kB
Slab:91.276kB//kernel數(shù)據(jù)結(jié)構(gòu)的緩存大小躯保,Slab=SReclaimable+SUnreclaim
SReclaimable:32.484kB//可回收的slab的大小
SUnreclaim:58.792kB//不可回收slab的大小
KernelStack:25.024kB
PageTables:23.752kB//以最低的頁表級
NFS_Unstable:0kB//不穩(wěn)定頁表的大小
Bounce:0kB
WritebackTmp:0kB
CommitLimit:1952.800kB
Committed_AS:82204.348kB//評估完成的工作量,代表最糟糕case下的值澎语,該值也包含swap內(nèi)存
VmallocTotal:251658.176kB//總分配的虛擬地址空間
VmallocUsed:166.648kB//已使用的虛擬地址空間
VmallocChunk:251398.700kB//虛擬地址空間可用的最大連續(xù)內(nèi)存塊
對于cache和buffer也是系統(tǒng)可以使用的內(nèi)存途事。所以系統(tǒng)總的可用內(nèi)存為 MemFree+Buffers+Cached
4.free
主功能:查看可用內(nèi)存,缺省單位KB擅羞。該命令比較簡單尸变、輕量,專注于查看剩余內(nèi)存情況减俏。數(shù)據(jù)來源于/proc/meminfo召烂。
輸出結(jié)果:
Java
1
2
3
4
5root@phone:/proc/sys/vm#free
totalusedfreesharedbuffers
Mem:285703218360401020992075104
-/+buffers:17609361096096
Swap:5242840524284
對于Mem行,存在的公式關(guān)系: total = used + free;
對于-/+ buffers行: 1760936 = 1836040 – 75104(buffers); 1096096 = 1020992 + 75104(buffers);
5. showmap
主功能:用于查看虛擬地址區(qū)域的內(nèi)存情況
Java
1
用法:showmap-a[pid]
該命令的輸出每一行代表一個虛擬地址區(qū)域(vm area)
Java
1
2
3
4
5root@phone:/#showmap-a10901
startendvirtualsharedsharedprivateprivate
addraddrsizeRSSPSScleandirtycleandirtyobject
------------------------------------------------------------------------------------------------------
f3b87000f3d850002040440040/dev/binder
start addr和end addr:分別代表進程空間的起止虛擬地址娃承;
virtual size/ RSS /PSS這些前面介紹過奏夫;
shared clean:代表多個進程的虛擬地址可指向這塊物理空間,即有多少個進程共享這個庫历筝;
shared: 共享數(shù)據(jù)
private: 該進程私有數(shù)據(jù)
clean: 干凈數(shù)據(jù)酗昼,是指該內(nèi)存數(shù)據(jù)與disk數(shù)據(jù)一致,當內(nèi)存緊張時梳猪,可直接釋放內(nèi)存麻削,不需要回寫到disk
dirty: 臟數(shù)據(jù),與disk數(shù)據(jù)不一致,需要先回寫到disk呛哟,才能被釋放叠荠。
功能與cat /proc/[pid]/maps基本一致。
6. vmstat
主功能:不僅可以查看內(nèi)存情況扫责,還可以查看進程運行隊列蝙叛、系統(tǒng)切換、CPU時間占比等情況公给,另外該指令還是周期性地動態(tài)輸出借帘。
用法:
Java
1
2
3
4Usage:vmstat[-niterations][-ddelay][-rheader_repeat]
-niterations數(shù)據(jù)循環(huán)輸出的次數(shù)
-ddelay兩次數(shù)據(jù)間的延遲時長(單位:S)
-rheader_repeat循環(huán)多少次,再輸出一次頭信息行
輸入結(jié)果:
Java
1
2
3
4
5
6
7
8root@phone:/#vmstat
procsmemorysystemcpu
rbfreemappedanonslabincsfltusnisyidwair
2066343623283691519211396019627408029900
0066344423283691510811396018026007039900
0066347623283691521611396015422402059900
10663132232836915304113960179259011039900
2066312423283691509611396011017504039900
參數(shù)列總共15個參數(shù)淌铐,分為4大類:
procs(進程)
r: Running隊列中進程數(shù)量
b: IO wait的進程數(shù)量
memory(內(nèi)存)
free: 可用內(nèi)存大小
mapped:mmap映射的內(nèi)存大小
anon: 匿名內(nèi)存大小
slab: slab的內(nèi)存大小
system(系統(tǒng))
in: 每秒的中斷次數(shù)(包括時鐘中斷)
cs: 每秒上下文切換的次數(shù)
cpu(處理器)
us: user time
ni: nice time
sy: system time
id: idle time
wa: iowait time
ir: interrupt time
小結(jié)
dumpsys meminfo適用場景: 查看進程的oom adj肺然,或者dalvik/native等區(qū)域內(nèi)存情況,或者某個進程或apk的內(nèi)存情況腿准,功能非常強大际起;
procrank適用場景: 查看進程的VSS/RSS/PSS/USS各個內(nèi)存指標;
cat /proc/meminfo適用場景: 查看系統(tǒng)的詳盡內(nèi)存信息吐葱,包含內(nèi)核情況街望;
free適用場景: 只查看系統(tǒng)的可用內(nèi)存;
showmap適用場景: 查看進程的虛擬地址空間的內(nèi)存分配情況弟跑;
vmstat適用場景: 周期性地打印出進程運行隊列灾前、系統(tǒng)切換、CPU時間占比等情況孟辑;
MemAvailable:MemFree+Active(file)+Inactive(file)-(watermark+min(watermark,Active(file)+Inactive(file)/2))
file占用的內(nèi)存是可以釋放的哎甲,但是釋放的過多,會導致swap發(fā)生
減去部分內(nèi)存的目的是避免swap