Android前端APP的性能测试一般针对以下几个方面:应用启动时间;CPU的占用;内存的占用;流量的耗用;电量的耗用;流畅度等。一般对App进行性能测试都需要借助不同的工具完成,本章节会向读者重点介绍针对不同的性能测试指标该选用哪种工具以及工具的具体使用方法。(文章很有用,但是有点长,建议收藏!)
因为Android 手机是Linux内核,最简单的命令就是使用top命令查看手机的 cpu、内存的占用情况。
具体操作:
PC中成功安装Android SDK
手机成功连接PC
Android手机 ->设置 ->开发者选项->USB调试(打上勾)
在cmd窗口中输入 adb shell ,进入adb shell命令模式
方法1:输入top 显示如下:
具体参数含义如下:
CPU占用率:
User 用户进程
System 系统进程
IOW
IO等待时间
IRQ 硬中断时间
CPU使用情况(指一个最小时间片内所占时间,单位jiffies。或者指所占进程数):
User 处于用户态的运行时间,不包含优先值为负进程
Nice 优先值为负的进程所占用的CPU时间
Sys 处于核心态的运行时间
Idle 除IO等待时间以外的其它等待时间
IOW
IO等待时间
IRQ 硬中断时间
SIRQ 软中断时间
进程属性:
PID 进程在系统中的ID
CPU% 当前瞬时所以使用CPU占用率
S 进程的状态,其中S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值是负数。
#THR 程序当前所用的线程数
内存:
VSS
Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
RSS
Resident Set Size 实际使用物理内存(包含共享库占用的内存)
UID 运行当前进程的用户id
Name 程序名称system_server
备注:内存占用大小有如下规律:VSS >=RSS >=PSS >=USS
PSS Proportional Set Size实际使用的物理内存(比例分配共享库占用的内存)
USS Unique Set Size进程独自占用的物理内存(不包含共享库占用的内存)
应用启动时间测试
adb shell am start -W –n /
am命令的详细使用方法请参考章节am与pm命令
注意:启动时间需要区分首次启动和非首次启动
耗电测试
请参考文章Android App 耗电的测试方法
流畅度和网络消耗测试
请参考文章详解移动应用测试神器PerfDog
接下来我来介绍几款Android sdk中自带的,可以帮助我们搞定性能问题的工具!
Dumpsys命令默认打印出当前系统所有服务信息
使用命令dumpsys | grep "DUMP OF SERVICE" 可以查看的内容包括:
DUMP OF SERVICE DockObserver:
DUMP OF SERVICE SurfaceFlinger:
DUMP OF SERVICE accessibility:
DUMP OF SERVICE account:
DUMP OF SERVICE activity:
DUMP OF SERVICE alarm:
DUMP OF SERVICE android.security.keystore:
DUMP OF SERVICEandroid.service.gatekeeper.IGateKeeperService:
DUMP OF SERVICE appops:
DUMP OF SERVICE appwidget:
DUMP OF SERVICE assetatlas:
DUMP OF SERVICE audio:
DUMP OF SERVICE backup:
DUMP OF SERVICE battery:
DUMP OF SERVICE batteryproperties:
DUMP OF SERVICE batterystats:
DUMP OF SERVICE bluetooth_manager:
DUMP OF SERVICE carrier_config:
DUMP OF SERVICE clipboard:
DUMP OF SERVICE commontime_management:
DUMP OF SERVICE connectivity:
DUMP OF SERVICE consumer_ir:
DUMP OF SERVICE content:
DUMP OF SERVICE country_detector:
DUMP OF SERVICE cpuinfo:
DUMP OF SERVICE dbinfo:
DUMP OF SERVICE device_policy:
DUMP OF SERVICE deviceidle:
DUMP OF SERVICE devicestoragemonitor:
DUMP OF SERVICE diskstats:
DUMP OF SERVICE display:
DUMP OF SERVICE display.qservice:
DUMP OF SERVICE dreams:
DUMP OF SERVICE drm.drmManager:
DUMP OF SERVICE dropbox:
DUMP OF SERVICE ethernet:
DUMP OF SERVICE fingerprint:
DUMP OF SERVICE gfxinfo:
DUMP OF SERVICE graphicsstats:
DUMP OF SERVICE imms:
DUMP OF SERVICE input:
DUMP OF SERVICE input_method:
DUMP OF SERVICE iphonesubinfo:
DUMP OF SERVICE isms:
DUMP OF SERVICE isub:
DUMP OF SERVICE jobscheduler:
DUMP OF SERVICE launcherapps:
DUMP OF SERVICE location:
DUMP OF SERVICE lock_settings:
DUMP OF SERVICE media.audio_flinger:
DUMP OF SERVICE media.audio_policy:
DUMP OF SERVICE media.camera:
DUMP OF SERVICE media.cameraxy:
DUMP OF SERVICE media.player:
DUMP OF SERVICE media.radio:
DUMP OF SERVICE media.resource_manager:
DUMP OF SERVICE media.sound_trigger_hw:
DUMP OF SERVICE media_projection:
DUMP OF SERVICE media_router:
DUMP OF SERVICE media_session:
DUMP OF SERVICE meminfo:
DUMP OF SERVICE midi:
DUMP OF SERVICE mount:
DUMP OF SERVICE netpolicy:
DUMP OF SERVICE netstats:
DUMP OF SERVICE network_management:
DUMP OF SERVICE network_score:
DUMP OF SERVICE nfc:
DUMP OF SERVICE notification:
DUMP OF SERVICE package:
DUMP OF SERVICE permission:
DUMP OF SERVICE persistent_data_block:
DUMP OF SERVICE phone:
DUMP OF SERVICE power:
DUMP OF SERVICE print:
DUMP OF SERVICE processinfo:
DUMP OF SERVICE procstats:
DUMP OF SERVICE restrictions:
DUMP OF SERVICE rttmanager:
DUMP OF SERVICE samplingprofiler:
DUMP OF SERVICE scheduling_policy:
DUMP OF SERVICE search:
DUMP OF SERVICE sensorservice:
DUMP OF SERVICE serial:
DUMP OF SERVICE servicediscovery:
DUMP OF SERVICE simphonebook:
DUMP OF SERVICE sip:
DUMP OF SERVICE statusbar:
DUMP OF SERVICE telecom:
DUMP OF SERVICE telephony.registry:
DUMP OF SERVICE textservices:
DUMP OF SERVICE trust:
DUMP OF SERVICE uimode:
DUMP OF SERVICE updatelock:
DUMP OF SERVICE usagestats:
DUMP OF SERVICE usb:
DUMP OF SERVICE user:
DUMP OF SERVICE vibrator:
DUMP OF SERVICE voiceinteraction:
DUMP OF SERVICE wallpaper:
DUMP OF SERVICE webviewupdate:
DUMP OF SERVICE wifi:
DUMP OF SERVICE wifip2p:
DUMP OF SERVICE wifiscanner:
DUMP OF SERVICE window:
关键信息显示:
activity:显示所有的activities的信息
cpuinfo:显示CPU信息
window:显示键盘,窗口和它们的关系
wifi:显示wifi信息
batteryinfo $package_name:电量信息及CPU 使用时长
package packagename:获取安装包信息
usagestats:每个界面启动的时间
statusbar:显示状态栏相关的信息
meminfo:内存信息(meminfo $package_name or $pid使用程序的包名或者进程id显示内存信息)
diskstats:磁盘相关信息
battery:电池信息
alarm:显示Alarm信息
例如,输出某个应用的cpu信息,可以使用命令
dumpsys cpuinfo |your app package
am全称activity manager,使用am可以模拟各种系统的行为,例如去启动一个activity,强制停止进程,发送广播进程,修改设备屏幕属性等等。
pm全称package manager,你能使用pm命令去模拟android行为或者查询设备上的应用等等。
GPU:Graphic Processing Unit (图形处理器),主要反映应用的卡顿现象。
IOS与Android流畅与否的比较,主要是以下三个原因:
当滑动界面然后松手,这时界面会继续滑动,然后速度减小,直到速度为0时停止。iOS下速度减小的这个过程比较慢,尤其是快要停的时候是慢慢停的,视觉上有种很顺滑的感觉;Android下则从松手到停要快很多,相比之下有种戛然而止的感觉。
从数据/技术角度来看这个事情,我们滑动界面的最终目的不是为了“动”,而是为了“停”,因此只要平滑地到达目的地,似乎越快完成这个过程越好,所以Android的选择是理所当然的。但事实是,大家普遍更喜欢iOS的方式,这样做显得更顺滑、更优雅。
帧率:FPS是图像领域中的定义,是指画面每秒传输帧数,通俗来讲就是指动画或视频的画面数。30FPS是一般录像的常用帧数,30FPS在快速动作的时候会感觉不流畅。60FPS是一般游戏的常用帧数。
绝大部分时间两者(Android和IOS)都能保持60FPS左右的满帧率。但都会有偶尔的掉帧。并且Android上要比IOS上严重很多。掉帧导致卡顿,用户必然会感觉到掉帧那一刻的不流畅。
从手指碰到触摸屏,到屏幕上显示处理这次触摸产生的画面,是需要时间的。时间越短感觉越跟手。在软件系统层面,Android的显示机制是app-->SurfaceFlinger-->Display,这比传统的app-->Display多了一步,主要基于这个原因,画面最终输出到屏幕要比传统的方式慢一帧(16.7ms)。
综合分析:
第1点造成的影响最大,恰恰却是与技术/设备无关的。如果Android app或者Android系统要改变,很容易就可以调得跟IOS一模一样。但正是由于这是产品形态上的差别而不是纯粹技术上的优劣,反倒成了Android最不太可能改变的。
第2点的影响其次,当然是指在目前这个大部分时候都能满帧的情况下。这方面是Android从早期到现在进步最明显的方面,使用了很多方法来优化帧率。但就算现在Android进化了很多,硬件性能也进化了很多,却仍旧不可能彻底消灭掉帧的情况。
第3点通俗的讲就是跟手性,跟手性的重要性不言而喻,但现在的差别比较细微。
前提条件:android系统4.0+
“开发者选项”->“GPU呈现模式分析”->“在屏幕上显示为条形图”,如下图所示:
屏幕上有条绿色线(基准线)大概是16ms,如果超过这条线则很有可能掉帧了
蓝色代表测量绘制Display List的时间
红色代表OpenGL渲染Display List所需要的时间
黄色代表CPU等待GPU处理的时间
过度绘制指在屏幕的一个像素上绘制多次,我们对于UI性能的优化还可以通过开发者选项中的GPU过度绘制工具来进行分析。在设置->开发者选项->调试GPU过度绘制(不同设备可能位置或者叫法不同)中打开调试后可以看见如下图2(对settings当前界面过度绘制进行分析):
颜色的含义:
Device Monitor是一个用来给Android 程序进行调试和分析的工具
包括:
DDMSTracerfor OpenGL ESHierarchyViewerTraceview
启动方式
Cmd窗口中 进入sdk目录中的 ools
输入: monitor
前提条件:手机要root,否则好多功能用不了
uiautomatorviewer 是一个图形界面工具来扫描和分析应用的UI控件。uiautomatorviewer通过ADB向设备侧发送一个dump命令,下载一个包含当前界面控件布局信息的xml文件。
Dump view hierarchy for ui automator
Traceview是android平台配备的一个很好的性能分析工具,堪比java的性能调优工具visualvm线程视图,可以方便的查看线程的执行情况,某个方法执行时间、调用次数、在总体中的占比等,从而定位性能点。
启动:点击下图中的Start method Profiling
如下图所示:
a.Incl表示将所有子函数耗时也计算在内,Excl则表示不包括子函数的调用时间。对比可以确定耗时操作发生是自身还是子函数中。
b.Cpu Time表示占用cpu执行的时间,Real Time包括Cpu
Time以及等待、切换的时间等,所以一般都大于Cpu Time。对比可以判断耗时操作是否在cpu执行段内。
c. 上面四个指标对应的%表示函数在总时间的占比。方便查看某个函数的时间占比。
d.Calls+RecurCalls/Total表示被外部调用次数+递归次数/总次数。可以查看调用次数是否符合自己预期。
e.Cpu Time/Call, Real Time/Call表示总的Cpu Time及Real Time与总调用次数的比例。查看每次调用的耗时,一般可通过简单此项确定每个函数的性能。点击Devices Tab中的Start Method Profiling 按钮,需要停止时再次点击该按钮即可。
概念:DDMS 的全称是Dalvik Debug Monitor Service,它为我们提供例如:为测试设备截屏,针对特定的进程查看正在运行的线程以及堆信息、Logcat、广播状态信息、模拟电话呼叫、接收SMS、虚拟地理坐标等等。DDMS将搭建起IDE与测试终端(Emulator或者connected device)的链接,它们应用各自独立的端口监听调试器的信息,DDMS可以实时监测到测试终端的连接情况。当有新的测试终端连接后,DDMS将捕捉到终端的ID,并通过adb建立调试器,从而实现发送指令到测试终端的目的。
在monitor中启动DDMS ,打开\Sdk ools\monitor.bat,如下图所示:
logcat是Android中一个命令行工具,可以用于得到程序的log信息
Android日志信息都有一个标签和它的优先级.
日志的标签是系统部件原始信息的一个简要的标志。(比如:“View”就 是查看系统的标签)
下列优先级是按照从低到高顺序排列的:
V —Verbose (lowest priority)
D —Debug
I —Info
W —Warning
E —Error
F —Fatal
S —Silent (highest priority, on which nothing is ever printed)
查看进程包含的线程信息
查看进程使用的堆情况
点击GC可以进行对象回收;
判断内存泄露:一般情况下,在data object行的“Total Size”这个值得大小决定了是否会有内存泄漏。
a) 不断的操作当前应用,同时注意观察data
object的Total Size值;
b) 正常情况下Total Size值都会稳定在一个有限的范围内,也就是说由于程序中的的代码良好,没有造成对象不被垃圾回收的情况,所以说虽然我们不断的操作会不断的生成很多对象,而在虚拟机不断的进行GC的过程中,这些对象都被回收了,内存占用量会回落到一个稳定的水平;
c) 反之如果代码中存在没有释放对象引用的情况,则data
object的Total Size值在每次GC后不会有明显的回落,随着操作次数的增多Total Size的值会越来越大,
直到到达一个上限后导致进程被杀掉。
参数含义:
1)Data Object:java object.
2)Class Object:object of type Class, e.g. what you'd get fromjava.lang.String.class or myObject.getClass( ).
3)1,2,4,8-byte array:Number of bytes per entry.
1-byte array: byte, boolean
2-byte array: char, short
4-byte array: float, int
8-byte array: double, long
4)non-Java object:A non-Java Object is a piece of memory that isn't actuallyaccessible from code written in Java. Essentially it's a blob of stuff that gotstuck on the virtual heap but has no meaning to interpreted code. Shouldn't bemuch of that.
分析内存是否泄露:
通过mat 打开com.android.browser.hprof,分析内存
在使用mat前必须转化 ools\hprof-conv input.hprofoutput.hprof
查看Android系统的目录文件,常用目录和文件说明如下:
1、/mnt 挂载点目录
2、/etc 系统主要配置文件
3、/system Android系统文件
4、/sys Linux 内核文件
5、/proc 运行时文件
6、/init.rc 启动脚本
7、/defaultp 系统属性配置文件
8、/data 用户程序目录
9、/dev 存放与设备(包括外设)有关的文件(unix和linux系统均把设备当成文件)
查看线程中对象被分配的内存情况
Systrace是Android4.1中新增的性能数据采样和分析工具。它可帮助开发者收集Android关键子系统(如surfaceflinger、WindowManagerService等Framework部分关键模块、服务)的运行信息,从而帮助开发者更直观的分析系统瓶颈,改进性能。 注意:手机的内核一定要支持trace(可以查看是否存在/sys/kernel/debug/tracing 这个目录),
Systrace的功能包括跟踪系统的I/O操作、内核工作队列、CPU负载以及Android各个子系统的运行状况等。在Android平台中,它主要由3部分组成:
内核部分:Systrace利用了Linux Kernel中的ftrace功能。所以,如果要使用Systrace的话,必须开启kernel中和ftrace相关的模块。
数据采集部分:Android定义了一个Trace类。应用程序可利用该类把统计信息输出给ftrace。同时,Android还有一个atrace程序,它可以从ftrace中读取统计信息然后交给数据分析工具来处理。
数据分析工具:Android提供一个systrace.py(python脚本文件,位于Android SDK目录
/tools/platform-tools/systrace中)用来配置数据采集的方式(如采集数据的标签、输出文件名等)和收集 ftrace统计数据并生成一个结果网页文件供用户查看。
从本质上说,Systrace是对Linux Kernel中ftrace的封装(ftrace 的作用是帮助开发人员了解 Linux 内核的运行时行为,以便进行故障调试或性能分析。)。应用进程需要利用Android提供的Trace类来使用Systrace。
点击下图中的Capture SystemWide trace
可以设置抓取的系统参数如下:
备注:trace.html需要使用google chrome浏览器才能打开分析