移动端 - Android客户端性能测试
应用的性能测试
包括很多测试项,如启动时间、内存、CPU、GPU、功耗、流量等。
对于启动时间、内存、cpu 一般都使用外部提供的第三方工具来辅助测试,如GT、安测试,这些工具的原理都是基于调用 android 底层的一些 api 来获取到测试所用到的值,当然我们也可以采用其他方法,如使用 android 本身提供的一套 adb 即可完成上述测试。
对于 GPU、功耗等测试来说,用第三方工具测试得到的数值一般都不是很准确,这个时候我们需要引入硬件来进行测试了,GPU 可以采用高速相机来进行测试,功耗可以使用万用表或安捷伦电源仪来进行测试(ps:有硬件动手能力的可以DIY一个小板进行)
一、内存
关于内存测试需要引入空闲状态、中等规格、满规格的概念。
1、空闲状态
指打开应用后,点击home键让应用后台运行,此时应用处于的状态叫做空闲。2、中等规格和满规格
指的是对应用的操作时间的间隔长短不一,中等规格时间较长,满规格时间较短。
接下来我们说说在内存测试中,存在很多测试子项,如下清单所示
1)空闲状态下的应用内存消耗情况
2)中等规格状态下的应用内存消耗情况
3)满规格状态下的应用内存消耗情况
4)应用内存峰值情况
5)应用内存泄露情况
6)应用是否常驻内存
7)压力测试后的内存使用情况
3、如何使用adb查看内存信息
1)查看所有内存信息
命令:dumpsys meminfo
例:
C:\Users\yijiayi>adb shell
shell@android:/ $ dumpsys meminfo
2)查看某个包的内存信息
命令:dumpsys meminfo pkg_name or pid
注:pid可以通过 adb shell top | grep app_name 来查找
例:
C:\Users\yijiayi>adb shell
shell@android:/ $ dumpsys meminfo com.tencent.mobileqq
或
shell@android:/ $ dumpsys meminfo 1034(注:1034是pid)
重点关注如下几个字段:
(1) Native/Dalvik 的 Heap 信息
具体在上面的第一行和第二行,它分别给出的是JNI层和Java层的内存分配情况,如果发现这个值一直增长,则代表程序可能出现了内存泄漏。
(2) Total 的 PSS 信息
这个值就是你的应用真正占据的内存大小,通过这个信息,你可以轻松判别手机中哪些程序占内存比较大了。
查询内存
其他参数含义: dalvik : dalvik使用的内存 native : native堆上的内存,指C\C++堆的内存(android 3.0以后bitmap就是放在这儿) other : 除了dalvik和native的内存,包含C\C++非堆内存······ Pss : 该内存指将共享内存按比例分配到使用了共享内存的进程 allocated : 已使用的内存 free : 空闲的内存 private dirty : 非共享,又不能被换页出去的内存(比如linux系统中为了提高分配内存速度而缓冲的小对象,即使你的进程已经退出,该内存也不会被释放) share dirty : 共享,但有不能被换页出去的内存
二、CPU
1)CPU频率设置过高时会导致过热,过热导致耗电更严重,CPU频率设置过低导致手机滞后,应用处理缓慢同样会导致耗电。更多时候,用户解决CPU超载问题只能关闭甚至卸载App,App就被Kill了!
注意:程序持续运行及操作过程中,内存不能一直增加,不然系统会自动kill掉该进程。
(1)空闲状态下的应用CPU消耗情况
(2)中等规格状态下的应用CPU消耗情况
(3)满规格状态下的应用CPU消耗情况
(4)应用CPU峰值情况
2)CPU的测试方法分为几类(使用adbshell脚本进行测试,查看Log数据):
1.使用android提供的adb shell dumpsys cpuinfo | grep packagename >D:\cpu.txt(获取指定进程使用cpu的详细信息)
2.使用top命令 adb shell top -n 1 | grep packagename>/address/cpu.txt (获取指定进程使用cpu的详细信息,且只刷新一次)
3. cat /proc/cpuinfo 获取cpu 硬件信息
6. cat /proc/stat
例:查询QQ的CPU使用情况
三、流量
可以借用网易的开源工具:Emmagee,或者腾讯开发的工具:GT
流量测试,同样需要引入几个名词
- 中等负荷:应用正常操作
- 高负荷:应用极限操作
流量测试包括以下测试项:
- 应用首次启动流量提示
- 应用后台连续运行 2 小时的流量值
- 应用高负荷运行的流量峰值
- 应用中等负荷运行时的流量均值
流量测试一般都是用软件来进行的,这里我们一般分为2类:
- 采用市场提供的第三方工具来进行测试,如流量宝之类的
- 自研工具进行测试
自研工具进行测试一般包含 2 类方法,
- 通过 tcpdump 抓包,再通过 wireshake 直接读取包信息来获得流量
- 首先获得被测应用的 uid 信息,可以通过 adb shell dumpsys package 来获取 然后在未操作应用之前,我们可以通过查看 adb shell cat /proc/uid_stat/uid/tcp_rcv adb shell cat /proc/uid_stat/uid/tcp_snd 获取到应用的起始的接收及发送的流量,然后我们再操作应用,再次通过上述 2 条命令可以获取到应用的结束的接收及发送的流量,通过相减及得到应用的整体流量消耗
四、电量
和竞品做对比测试,同一机型的测试机在不同时间,不同网络条件,不同功能使用的情况下分别测试电量使用情况。
命令:dumpsys battery
五、启动速度和滑动、界面切换速度
编写测试代码(AndroidInstrumentation),打桩到源码中,运行后通过log数据进行分析。
六、与服务器交互的网络速度
七、启动时间
关于应用的启动时间的测试,分为三类:
1. 首次启动
应用首次启动所花费的时间
2. 非首次启动
应用非首次启动所花费的时间
3. 应用界面切换
应用界面内切换所花费的时间
4、如何测试启动时间?
方法分为2类,一类为使用软件来测试,一类为使用硬件来测试。
1)使用 android 提供的 DisplayManager 来获取 activity 的启动时间吧,在这里我简单说下如何通过批处理来 DIY
- 通过日志过滤关键字 Displayed 来过滤所有 activity 所打印的,记录日志通过 adb logcat>/address/logcat.txt
- 然后使用find “Displayed” /address/logcat.txt>/newaddress/fl.txt
通过 activity 名来过滤获取所测应用 find “ActivityName” /newaddress/fl.txt>/newaddress/last.txt
通过计算 activity 最后剩余的时间之和即可
2)除了 DisplayManager 的打印时间方法后,还有通过关注 am 的启动时间及 DisplayManager 打印的结束时间,通过两者时间之间想减也能得到应用的启动时间,还有可以通过 PowerManager 来计算打印时间,在应用启动的时候,我们可以关注 ActivityManager-Launch 的变化来计算应用的启动时间,还有可以通过截图统计启动时间,对于自研应用,最效率的莫过于直接在程序中插入打印时间的节点了
3)硬件测试方法,这里我们可以使用高速相机或者手机,采用录像的方法把应用启动过程给录制下来,然后通过人工数帧或者程序数帧的方式计算启动时间
查看页面启动时间:手机需要root
以启动camera为例
adb shell am start -W com.mediatek.camera/com.android.camera.CameraActivity
ubuntu@ubuntu:/media/disk/work/core$ adb shell am start -W com.mediatek.camera/com.android.camera.CameraActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER]
cmp=com.mediatek.camera/com.android.camera.CameraActivity }
Status: ok
Activity: com.mediatek.camera/com.android.camera.CameraActivity
ThisTime: 2871
TotalTime: 2871
WaitTime: 2949
Complete
格式为adb shell am start -W 包名/全类名或叫activity名
打印的结果为
ThisTime 该activity启动耗时
TotalTime 应用自身启动耗时=ThisTime+应用application等资源启动时间
WaitTime 系统启动应用耗时=TotalTime+系统资源启动时间
在测试该启动时间时需要理解两个概念
冷启动:应用第一次启动
热启动:按back按键后再启动或非第一次启动切没有清除该应用后台或缓存数据
上面的数据为冷启动打印的数据,下面运行热启动的测试结果:
ubuntu@ubuntu:/media/disk/work/core$ adb shell am start -W com.mediatek.camera/com.android.camera.CameraActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.mediatek.camera/com.android.camera.CameraActivity }
Status: ok
Activity: com.mediatek.camera/com.android.camera.CameraActivity
ThisTime: 1848
TotalTime: 1848
WaitTime: 1895
Complete
该命令具体实现在/frameworks/base/cmds/am/src/com/android/commands/am/Am.java,原理是跨Binder调用ActivityManagerService.startActivityAndWait() 接口,其中返回数据分别调用对应
startTime: 调用startActivityAndWait()的时间点
endTime: 调用startActivityAndWait()函数调用返回的时间点
WaitTime: 调用startActivityAndWait()调用耗时。
再通过之间的计算得到
4)另外一种方法:
命令:
adb logcat -c && adb logcat -f /mnt/sdcard/up.txt -s tag
选项说明
-c 清屏
-f 指定运行结果输出文件,默认输出到标准设备(一般是显示器
-s 设置默认的过滤级别为Silent
tag 仅显示priority/tag
更多信息烦请参考 adb logcat -help
例:
先启动app,然后执行如下命令
C:\Users\laiyu>adb logcat -c && adb logcat -f /mnt/sdcard/up.txt -s ActivityMana
ger
八、GPU性能测试
关于GPU的几个名词,过度绘制、帧率、帧方差(过度绘制是指界面显示的 activity 套接了多层而导致。帧率是指屏幕刷新率。帧方差是指屏幕刷新帧间隔方差。)
对于 GPU 的测试主要包括以下几个测试子项
1)界面过度绘制:对于过度绘制的测试主要通过人工进行测试,通过打开开发者选项中的 显示GPU过度绘制 来进行测试(PS:只有android4.2及以上的版本才具备此功能),验收的标准为:
- 不允许出现黑色像素
- 不允许存在4x过度绘制
- 不允许存在面积超过屏幕1/4区域的3x过度绘制(淡红色区域)
2)屏幕滑动帧速率:对于屏幕滑动帧速率主要有 2 种方法。
先说说软件测试的方法:
1.手机端需打开开发者选项中的 启用跟踪 后勾选 Graphics 和 View
2.启动 SDK 工具 Systrace 插件,勾选被测应用,点击 Systrace 插件,在弹出的对话框中设置持续抓取时间,在trace taps下面勾选 gfx 及 view 选项,
3.人滑动界面可以通过节拍来进行滑动或者扫动,帧率数据会保存到默认路径下,默认名称为 trace.html
4.将trace.html文件拷贝到linux系统下 通过命令进行转换,生成trace.csv文件
grep 'postFramebuffer' trace.html | sed -e 's/.*]\W*//g' -e 's/:.*$//g' -e 's/\.//g' > trace.csv
5.用excel打开文件计算得到帧率
接下来我们说说硬件的方法,这里需要引入高速相机,打开高速相机,开启摄像模式,录制人滑动或者扫动被测应用的视频,再通过人工或者程序数帧的方法对结果进行计算得到帧率
3)屏幕滑动平滑度:
对于屏幕滑动平滑度的测试,方法如同帧率测试,唯一的差异就是最后的结果计算公式的差异
GPU的测试目前业界使用的均为硬件来进行,软件测试的数据相较硬件差异较大,对于帧率及帧方差的测试标准而言,需对待不同机型设定不同的标准
九、功耗测试
功耗测试主要从以下几个方面入手进行测试
- 测试手机安装目标APK前后待机功耗无明显差异
- 常见使用场景中能够正常进入待机,待机电流在正常范围内.
- 长时间连续使用应用无异常耗电现象
功耗测试的方法分为两类,一类为软件测试,一类为硬件测试
我们先说说软件测试,这里我们会聊聊一些DIY的思路,软件测试一般分为2类,
- 第一种采用市场上提供的第三方工具,如金山电池管家之类的。
- 第二种就是自写工具进行,这里一般会使用3种方法
- 第一种基于android提供的PowerManager.WakeLock来进行,
- 第二种比较复杂一点,功耗的计算=CPU消耗+Wake lock消耗+数据传输消耗+GPS消耗+Wi-Fi连接消耗,
- 第三种通过 adb shell dumpsys battery来获取
接着说硬件测试,在这里我们一般使用万用表或者功耗仪进行测试,使用功耗仪测试的时候,需要制作假电池来进行的,有些不能拔插电池的手机还需要焊接才能进行功耗测试。
移动端相关功耗测试杂谈:
1、为什么要测功耗?测功耗的实际意义有哪些?
ROM级别的,测功耗(包括其自带的应用)是必然的(毕竟rom的耗电决定待机时间长短,这是手机的很重要卖点之一,也是用户比较关心的一个指标)。一般官方宣传的手机资料时,里面写的待机时间多少分钟、2G/3G通话/上网多少分钟、wifi上网/听音乐/播放视频的最大时长,就是测耗电量再经过计算得来的。
单个App级别的,大家都知道,耗电量的增加,也就意味着内存/CPU占用的增加。正所谓,透过现象看本质,如果增幅较之前版本过大,那很有可能是代码出问题了(即便不影响功能使用,这种问题即便不修正不优化,但最好能做到知道哪有问题);比之前版本过小,时间精力够的话最好去找找导致差异过大的原因。
(PS:像ROM级别的功耗测试这肯定是各个厂商都会做的,咱们普通小老百姓基本无需操心这些。非系统自带的App,尤其是安卓平台,在海量的ROM下,用户量比较大的应用,可以去着重在各种ROM上看看耗电量还可以;一般的应用,我个人愚见,测耗电量的意义和回报不太大,还不如多关注UI设计、优化内存CPU的占用、优化各功能的响应时间的更有意义,因此测App的功耗视需求而定。)
2、测功耗大致过程是怎样?
测功耗,一般是选取(经过细致评估的App或ROM的功能性能)比较稳定的版本来做一轮功耗测试,测时用两三个硬件没什么问题的手机、刷个干净稳定的系统,让手机、假电池、电流表串联(即假电池连接到电流表的电流输出口,然后再安到手机上模拟日常用的电池来给手机供电,这样保证三者电流一致),和然后放上SIM卡(一般是移动的),然后去测各种功能下的耗电量。
比如,测理论上的手机2G通话的最大时长,打几个十分钟的电话,采集并计算这段时间系统的电流的平均值,然后再用该手机配备的电池的容量除以这个电流值即得出理论上的2G最大通话时间。测单个功能的功耗,只要减掉手机待机时的电流值即得到单个功能的功耗。
(PS:上面有些理论是从别的博客摘抄记录下来的,但具体没有记录是哪些博客,所以这里就不贴原博客地址了,但实际的操作是自己做的)