Android 终端性能测试——内存篇
做Android QQ性能测试时,内存测试中遇到不少困惑,”各种”内存术语,到底什么意思,怎么获取,这里总结一下。
进行的内存测试主要有两个方面,一,OOM的发现和定位,二,同历史版本或竞品的对比测试。关于oom可以用MAT进行分析,具体分析方法参见susanwu在km上的文章《如何使用Memory_Analyzer分析内存泄漏》。下面主要总结一下Android性能 测试中常用的方法及解释
一:running services"查看service进程内存
从Android 2.0开始,在Settings中加入了一个新的activity("Running Services" activity),它用于显示当前运行的每个Services进程的内存使用情况及整个手机的内存大致使用情况。可以通过Setting->Applications->Running services进入该activity。
使用该方法需要注意,一些应用程序可能有几个进程,但是在这里只显示了其中的某个进程。比如微信,在Running services activity 只能看到子进程com.tencent.mm:push的内存信息,所以,这个统计有时候是不可靠的。
二:常用的shell命令获取:
1. Procrank命令,Procrank 可以同时获得以下几种内存的信息:
need-to-insert-img
l VSS:Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)。This size also includes memory that may not be resident in RAM like mallocs that have been allocated but not written to,所以用VSS来衡量一个进程实际使用的内存意义不大。
l RSS : Resident Set Size 实际使用物理内存(包含共享库占用的内存)。 RSS can be misleading, because it reports the total all of the shared libraries that the process uses, even though a shared library is only loaded into memory once regardless of how many processes use,所以用RSS来衡量进程占用的内存信息不是特别准确。
l PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)。 PSS is a very useful number because when the PSS for all processes in the system are summed together, that is a good representation for the total memory usage in the system,所以用pss衡量程序占用的内存误差比较小。
l USS - Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存).USS is an extremely useful number because it indicates the true incremental cost of running a particular process,所以用USS描述进程占用内存的波动和峰值比较有意义。
一般存在以下关系VSS>=RSS>=PSS>=USS。
如果要获得某个进程的内存信息,用procrank是个不错的选择,但是目前很多android系统都不支持这个命令,HTC手机部分原生系统支持,比如g3的2.2.1rom。
2. Top命令
输入命令行adb shell top,输出如下图所示:列出top*进程的cpu和内存占用情况,默认按照cpu占用降序排列。top可以获得进程的VSS和RSS信息,命令持续的监视,所以个人觉得这是一个快速查看进程内存和cpu的好方法。
need-to-insert-img
3. Ps命令
PS命令可以获得应用程序的VSIZE(VSS)和RSS,PS是一个获得的是应用的瞬间状态,不需要退出确认,因此在自动化脚本上比较好用。ps | grep appName直接输出appName进程对应的内存信息。
need-to-insert-img
4. dumpsys meminfo
dumpsys 用来给出手机中所有应用程序的信息,并且也会给出手机的状态。用以下命令可以查看程序的内存使用情况:adb shell dumpsys meminfo $package_name or $pid //使用程序的包名或者进程id
下图是查看pid为767的应用内存信息截图。
need-to-insert-img
android程序内存被分为2部分:native和dalvik,dalvik就是我们平常说的java堆,我们创建的对象是在这里面分配的,而bitmap是直接在native上分配的,对于内存的限制是native+dalvik不能超过最大限制。android程序内存一般限制在16M和24M
size :总内存大小(kb)。
Allocated:表示的是已使用了的内存大小(kb),
Free:表示的是剩余的内存大小(kb)
PrivateDirty:非共享的,又不能换页出去(can not be paged to disk )的内存的大小。和USS相似,但是实际实践中,发现他们还是有细微的差别,现在还没有搞明白。
SharedDirty:参照PrivateDirty我认为它应该是指共享的,又不能换页出去(can not be paged to disk )的内存的大小。比如Linux为了提高分配内存速度而缓冲的小对象,即使所有共享它的进程结束,该内存也不会释放掉,它只是又重新回到缓冲中而已。
5. adb shell cat /proc/meminfo
该方式只能得出系统整个内存的大概使用情况。
need-to-insert-img
MemTotal :可供系统和用户使用的总内存大小 (它比实际的物理内存要小,因为还有些内存要用于radio, DMA buffers, 等).
MemFree:剩余的可用内存大小。这里该值比较大,实际上一般Android system 的该值通常都很小,因为我们尽量让进程都保持运行,这样会耗掉大量内存。
Cached: 系统用于文件缓冲等的内存. 通常systems需要20MB 以避免bad paging states。
6. cat /proc/$pid/status
以下是进程ID为767的应用程序的status,其中state可以看出该应用目前的状态sleeping或running等。
need-to-insert-img
VmSize(KB) :任务虚拟地址空间的大小(total_vm-reserved_vm),其中total_vm为进程的地址空间的大小,reserved_vm:进程在预留或特殊的内存间的物理页
VmLck(KB)
:任务已经锁住的物理内存的大小。锁住的物理内存不能交换到硬盘
VmRSS(KB):
应用程序正在使用的物理内存的大小,和RSS值基本相同
KeyEvent ValueKEYCODEComment
0KEYCODE_UNKNOWN
1KEYCODE_MENU在SDK2.1的模拟器中命令失效,sendevent命令可行
2KEYCODE_SOFT_RIGHT
3KEYCODE_HOME
4KEYCODE_BACK
5KEYCODE_CALL
6KEYCODE_ENDCALL
7KEYCODE_0
8KEYCODE_1
9KEYCODE_2
10KEYCODE_3
11KEYCODE_4
12KEYCODE_5
13KEYCODE_6
14KEYCODE_7
15KEYCODE_8
16KEYCODE_9
17KEYCODE_STAR
18KEYCODE_POUND
19KEYCODE_DPAD_UP
20KEYCODE_DPAD_DOWN
21KEYCODE_DPAD_LEFT
22KEYCODE_DPAD_RIGHT
23KEYCODE_DPAD_CENTER
24KEYCODE_VOLUME_UP
25KEYCODE_VOLUME_DOWN
26KEYCODE_POWER
27KEYCODE_CAMERA
28KEYCODE_CLEAR
29KEYCODE_A
30KEYCODE_B
31KEYCODE_C
32KEYCODE_D
33KEYCODE_E
34KEYCODE_F
35KEYCODE_G
36KEYCODE_H
37KEYCODE_I
38KEYCODE_J
39KEYCODE_K
40KEYCODE_L
41KEYCODE_M
42KEYCODE_N
43KEYCODE_O
44KEYCODE_P
45KEYCODE_Q
46KEYCODE_R
47KEYCODE_S
48KEYCODE_T
49KEYCODE_U
50KEYCODE_V
51KEYCODE_W
52KEYCODE_X
53KEYCODE_Y
54KEYCODE_Z
55KEYCODE_COMMA
<td style="padding:0pt 5.4pt;width:96.35pt" valign="bottom"