一、android性能测试工具有哪些
1、android针对上面这些会影响到应用性能的情况提供了一些列的工具:
2、hierarchyviewer:检测布局复杂度,各视图的布局耗时情况:
3、Android开发者模式—GPU过渡绘制:
4、2耗电量:Android开发者模式中的电量统计;
5、应用运行时内存使用情况查看:Android Studio—Memory/CPU/GPU;
6、4网络:Android Studio—NetWork;
7、静态代码检查工具:Android studio—analyze—Inspect Code.../Code cleanup...,用于检测代码中潜在的问题、存在效率问题的代码段并提供改善方案;
8、DDMS—TraceView,用于查找程序运行时具体耗时在哪;
9、StrictMode:用于查找程序运行时具体耗时在哪,需要集成到代码中;
10、Andorid开发者模式—GPU呈现模式分析。
11、6程序稳定性:monkey,通过monkey对程序在提交测试前做自测,可以检测出明显的导致程序不稳定的问题,执行monkey只需要一行命令,提交测试前跑一次可以避免应用刚提交就被打回的问题。
12、上面提到的这些工具可以进Android开发者官网性能工具介绍查看每个工具的介绍和使用说明;
13、Android开发者选项中有很多测试应用性能的工具,对应用性能的检测非常有帮助,具体可以查看:All about your phone's developer options和15个必知的Android开发者选项对Android开发者选项中每一项的介绍;
14、针对Android应用性能的优化,Google官方提供了一系列的性能优化视频教程,对应用性能优化具有非常好的指导作用,具体可以查看:优酷Google Developers或者Android Performance Patterns。
15、除了android官方提供的一系列性能检测工具,还有很多优秀的第三方性能检测工具使用起来更方便,比如对内存泄露的检测,使用leakcanry比MAT更人性化,能够快速查到具体是哪存在内存泄露。
16、leakcanary:square/leakcanary· GitHub,通过集成到程序中的方式,在程序运行时检测应用中存在的内存泄露,并在页面中显示,在应用中集成leancanry后,程序运行时会存在卡顿的情况,这个是正常的,因为leancanry就是通过gc操作来检测内存泄露的,gc会知道应用卡顿,说明文档:LeakCanary中文使用说明、LeakCanary:让内存泄露无所遁形。
17、GT:GT Home,GT是腾讯开发的一款APP的随身调测平台,利用GT,可以对CPU、内存、流量、点亮、帧率/流畅度进行测试,还可以查看开发日志、crash日志、抓取网络数据包、APP内部参数调试、真机代码耗时统计等等,需要说明的是,应用需要集成GT的sdk后,GT这个apk才能在应用运行时对各个性能进行检测。
二、Android P 系统稳定性问题分析方法总结
Android系统最开始是为手机设计的,在机顶盒,电视,带屏音箱等大屏上运行后,芯片厂家做些适配,产品厂家也会做系统客制化,有时候还要适配第三方应用..等待
这种适配容易引人系统的稳定性问题,系统稳定性对于用户体验至关重要,很多问题也都比较类似,android系统对系统性能,稳定性分析工具也比较多,下面根据工作中遇到的问题做个总结。
从表现来看有:死机重启,自动关机,无法开机,冻屏,黑屏以及闪退,无响应等情况;
从技术层面来划分无外乎两大类:长时间无法执行完成(Timeout)以及异常崩溃(crash).主要分类如下:
ANR(Application Not responding),是指普通app进程超过一定时间没有执行完,系统会弹出应用无响应对话框.如果
该进程运行在system进程,更准确的来说,应该是(System Not Responding, SNR)
ANR产生的原因可能是各种各样的,但常见的原因可以分为:
2.trace文件(保存在/data/anr/traces.txt)
从traces.txt可以看到线程的函数调用栈
10-16 00:50:10 820 907 E ActivityManager: ANR in com.android.systemui, time=130090695
10-16 00:50:10 820 907 E ActivityManager: Reason: Broadcast of Intent{ act=android.intent.action.TIME_TICK flg=0x50000114(has extras)}
10-16 00:50:10 820 907 E ActivityManager: Load: 30.4/ 22.34/ 19.94
10-16 00:50:10 820 907 E ActivityManager: Android time:[2015-10-16 00:50:05.76][130191,266]
10-16 00:50:10 820 907 E ActivityManager: CPU usage from 6753ms to-4ms ago:
10-16 00:50:10 820 907 E ActivityManager: 47% 320/netd: 3.1% user+ 44% kernel/ faults: 14886 minor 3 major
10-16 00:50:10 820 907 E ActivityManager: 15% 10007/com.sohu.sohuvideo: 2.8% user+ 12% kernel/ faults: 1144 minor
10-16 00:50:10 820 907 E ActivityManager: 13% 10654/hif_thread: 0% user+ 13% kernel
10-16 00:50:10 820 907 E ActivityManager: 11% 175/mmcqd/0: 0% user+ 11% kernel
10-16 00:50:10 820 907 E ActivityManager: 5.1% 12165/app_process: 1.6% user+ 3.5% kernel/ faults: 9703 minor 540 major
10-16 00:50:10 820 907 E ActivityManager: 3.3% 29533/com.android.systemui: 2.6% user+ 0.7% kernel/ faults: 8402 minor 343 major
10-16 00:50:10 820 907 E ActivityManager:+0% 12832/cat: 0% user+ 0% kernel
10-16 00:50:10 820 907 E ActivityManager:+0% 13211/zygote64: 0% user+ 0% kernel
10-16 00:50:10 820 907 E ActivityManager: 87% TOTAL: 3% user+ 18% kernel+ 64% iowait+ 0.5% softirq
发生ANR的时间 00:50:10,可以从这个时间点之前的日志中,还原ANR出现时系统的运行状态
发生ANR的进程 com.android.system.ui
发生ANR的原因 Reason关键字表明了ANR的原因是处理TIME_TICK广播消息超时
CPU负载 Load关键字表明了最近1分钟、5分钟、15分钟内的CPU负载分别是30.4、22.3、19.94.CPU最近1分钟的负载最具参考价值,因为ANR的超时限制基本都是1分钟以内,这可以近似的理解为CPU最近1分钟平均有30.4个任务要处理,这个负载值是比较高的
CPU使用统计时间段 CPU usage from XX to XX ago关键字表明了这是在ANR发生之前一段时间内的CPU统计,类似的还有CPU usage from XX to XX after关键字,表明是ANR发生之后一段时间内的CPU统计
以com.android.systemui进程的CPU使用率为例,它包含以下信息:
总的CPU使用率: 3.3%,其中systemui进程在用户态的CPU使用率是2.6%,在内核态的使用率是0.7%
缺页次数fault:8402 minor表示高速缓存中的缺页次数,343 major表示内存的缺页次数。minor可以理解为进程在做内存访问,major可以理解为进程在做IO操作。当前minor和major值都是比较高的,从侧面反映了发生ANR之前,systemui进程有有较多的内存访问操作,引发的IO次数也会较多
CPU使用汇总 TOTAL关键字表明了CPU使用的汇总,87%是总的CPU使用率,其中有一项iowait表明CPU在等待IO的时间,占到64%,说明发生ANR以前,有大量的IO操作。app_process、 system_server, com.android.systemui这几个进程的major值都比较大,说明这些进程的IO操作较为频繁,从而拉升了整个iowait的时间
----- pid 29533 at 2015-10-16 00:48:29-----
Cmd line: com.android.systemui
| group="main" sCount=1 dsCount=0 obj=0x75bd5818 self=0x7f8549a000
| sysTid=29533 nice=0 cgrp=bg_non_interactive sched=0/0 handle=0x7f894bbe58
| state=S schedstat=( 289080040422 93461978317 904874) utm=20599 stm=8309 core=0 HZ=100
| stack=0x7fdffda000-0x7fdffdc000 stackSize=8MB
at com.mediatek.anrappmanager.MessageLogger.println(SourceFile:77)
Android系统中,有硬件WatchDog用于定时检测关键硬件是否正常工作,类似地,在framework层有一个软件WatchDog用于定期检测关键系统服务是否发生死锁事件。
watchdog每过30s检测一次,如果要监控的线程30s后没有响应,系统会dump出此进程堆栈,如果超过60s没有相应,会触发watchdog,并重启系统
10:57:23.718 579 1308 W Watchdog:*** WATCHDOG KILLING SYSTEM PROCESS: Blocked in monitor com.android.server.am.ActivityManagerService on foreground thread(android.fg), Blocked in handler on main thread(main), Blocked in handler on ActivityManager(ActivityManager)
10:57:23.725 579 1308 W Watchdog: android.fg annotated stack trace:
10:57:23.726 579 1308 W Watchdog: at com.android.server.am.ActivityManagerService.monitor(ActivityManagerService.java:26271)
10:57:23.727 579 1308 W Watchdog:- waiting to lock<0x0bb47e39>(a com.android.server.am.ActivityManagerService)
10:57:23.727 579 1308 W Watchdog: at com.android.server.Watchdog DeliveryTracker.alarmTimedOut(AlarmManagerService.java:4151)
10:57:23.733 579 1308 W Watchdog:- waiting to lock<0x00aaee38>(a java.lang.Object)
10:57:23.736 579 1308 W Watchdog: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:838)
10:57:23.739 579 1308 W Watchdog: ActivityManager annotated stack trace:
10:57:23.740 579 1308 W Watchdog: at com.android.server.am.ActivityStack$ActivityStackHandler.handleMessage(ActivityStack.java:405)
10:57:23.740 579 1308 W Watchdog:- waiting to lock<0x0bb47e39>(a com.android.server.am.ActivityManagerService)
10:57:23.740 579 1308 W Watchdog: at android.os.Handler.dispatchMessage(Handler.java:106)
10:57:23.741 579 1308 W Watchdog:*** GOODBYE!
提示 ActivityManagerService的android.fg,main,ActivityManager线程Block了,但logcat里只能看到
android.fg等待0x0bb47e39锁,main等待0x00aaee38锁,ActivityManager等待0x0bb47e39锁,无法进一步分析,需要看traces.txt
当出现应用闪退,可以从两个方面查看:
可以通过logcat–s AndroidRuntime DEBUG过滤日志,查看应用奔溃的具体堆栈信息。
其中AndroidRuntime的TAG打印java层信息,DEBUG的TAG打印native层的信息。
2、是否被lowmemorykiller杀掉:
可以通过 logcat–s lowmemorykiller过滤日志,注意adj 0是代表前台进程。例如:
03-08 04:16:58.084 310 310 I lowmemorykiller: Killing'com.google.android.tvlauncher'(2520), uid 10007, adj 0
发生这种情况,需要dumpsys meminfo查看当前内存状态,是否有进程内存泄漏,导致系统内存不够,出现前台进程被杀,造成闪退。
测试过程中,经常遇到屏幕闪烁的现象,需要排除是OSD层闪烁,还是video层闪烁。
1、先通过android原生方法:screencap截图, screenrecord录制视频,这里都是截取的OSD层,查看是否有闪屏现象。
2、OSD没有问题,就需要从更底层的显示模块分析,一般需要芯片厂家提供debug手段,不同芯片厂家方案不一样。
3,有时候输出不稳定,hdmi/mipi信号干扰,输出频率异常等也会导致闪屏,这种情况需要硬件协助分析。
如果OSD层也闪烁,则需从系统和应用层面分析。如曾遇到在开机向导界面,有个应用不断被唤起,导致走开机向导时出现连续闪灰屏的现象。
黑屏分UI黑屏,视频播放黑屏但UI正常等,2种场景
1、screencap截屏,排查OSD层图形是否正常,
2、如果OSD图形正常,需要排查显示输出模块是否异常。
3、电视机里面屏显是单独控制,如果屏参配置错误会导致整改黑屏。
OSD异常,需要排查顶层activity是否黑屏,window是否有异常等.
1,排查视频图层或者window是否创建成功。
2,排查解码是否有异常,不同的应用youtube,netflix,iptv解码方式不一样,需要具体问题具体分析。
如下,ActivityManager因为空对象引用而挂掉,导致system_server重启
***[FATAL EXCEPTION IN SYSTEM PROCESS: ActivityHanager [
^ava.lang.NullPointerException: Attempt to invoke virtual method'void co®.android.internal.os.KernelSingleUidTimeReader.iBarkDataAsStale(boolean)' on a null object reference
at com.android.internal.os.BatteryStatsIiaplSConstants.upddteTrackCpuTiinesbyProcStdteLocked(BatteryStatslnpl.java:13355)
at com.android.internal.os.BatteryStatsInplSConstants.upddteConstants(BatteryStatsImpl.java:13330)
at com.android.internal-o-batteryStatslMpl$Constants-onChange(BatteryStatsInpl-java:13316)
at android.database.Contentobserver.onChange(ContentObserver.java:145)
DEBUG: pid: 296, tid: 1721, name: Binder:296_4>>>/system/bin/surfaceflinger<<<
DEBUG: signal 6(SIGABRT), code-6(SI_TKILL), fault addr------
DEBUG: Abort message:'status.cpp:149] Failed HIDL return status not checked: Status(EXTRANSACTIONFAILED):
DEBUG: r0 00000000 rl 000006b9
DEBUG: C4 00000128 r5 000006b9
DEBUG: r8 00000019 r9 0000015d
DEBUG: ip a6ablbec sp a235d5f8
/system/lib/libbase.so(android::base::DefaultAborter(char const)+6)
/system/lib/libsurfaceflinger.so
/system/lib/libsurfaceflinger.so
/system/lib/libsurfaceflinger.so
/system/lib/libsurfaceflinger.so
/system/lib/libbase.so(android::base::LogMessage::~LogMessage()+502)
/system/lib/libhidlbase.so(android::hardware::details::return_status::~return_status()+184)
(android::Hwc2::impl::Composer::getActiveConfig(unsigned long long, unsigned int)+56)
(HWC2::Display::getActiveConfig(std::_1::shared_ptr<HWC2::Display::Config const>*) const+38)
(android::HWComposer::getActiveConfig(int) const+64)
(android::SurfaceFlinger::resyncToHardwareVsync(bool)+64)
可以根据backtrace来进行定位异常崩溃的地方。Android P上, backtrace使用Java上下文来显示,省去使用addr2line来转换的一个过程,方便调试分析问题。但是实际场景中,
有些native进程崩溃只有pc地址,而无函数信息,或者需要定位到具体的某个文件某个函数,则可借助堆栈分析工具addr2line。
addr2line:根据堆栈定位具体函数和文件
addr2line-e libsurfaceflinger.so-f 00071a09
addr2line-e libsurfaceflinger.so-f 00071a09
_ZN7android14SurfaceFlinger12waitForEventEv
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp:1229
1、需用带debug信息的LINK目录里面的so库,机顶盒上的so库是无法定位的:
out/target/product/xx/obj/SHARED_LIBRARIES/libsurfaceflinger_intermediates/LINKED/libsurfaceflinger.so
或者:out/target/product/xx/symbols/system/lib/libsurfaceflinger.so
2、定位的文件,必现和机器上出现问题的版本一致,否则定位不准确
debuggerd:打印当前进程实时堆栈:debuggerd–b pid
Unable to handle kernel NULL pointer dereference at virtual address...
Unable to handle kernel paging request at virtual address...
Unhandled prefetch abort...at...
Out of memory and no killable processes...
PS:WARN_ON只dump stacks,kernel还是正常
[214.962667] 08:14:19.315(2)-0488 Unable to handle kernel paging request at virtual address 6b6b6cl7
[214.973889] 08:14:19.326(2)-0488 addr:6b6b6c17 pgd= d0824000
[214.980132][6b6b6c17J•pgd=O000eO0e
[214.983865] 08:14:19.336(2)-0488 Internal error: Oops: 805 [#1] PREEMPT smP ARM
[214.9914S3] Modules linked in: 8192eu ufsd(PO) jnl(O) fusion(O)
(215.001878] 08:14:19.354(2)-0488 CPU: 2 PID: 488 Comm: system_server Tainted: P 4.4.3+#113
(2)-0488 Hardware name: rtd284x
〃当前PC指针 98:14:19.377(2)-0488 PC is at mutex_unlo<k+0xc/0x38
(21S.024846] 08:14:19.383(2)-0488 LR is at storage_pm_event+0xb4/0xe8
//Registers 08:14:19.390(2)-0488:[<ceb78ffc>] Ir:[<C0542034>] psr: 200f0013
I 215.037644] sp: ccf79e38 ip: eceoeeee fp: 9b34648c
08:14:19.404(2)-0488 rlO: 00000080 r9:Cl8b3864 r8: oeeeeeoe
215.058692] 08:14:19.411(2)-0488 P7: C1293a98 P6:C1293940 r5: C1293940 r4:C1293a80
[ 215.076014] 08:14:19.420(2)-0488 r3: 00000033 r2:00000000 ri: 000^000 re:6b6b6c07
08:14:19.428(2)-0488 Flags: nzCv IRQs on FIQs on Mode SVC 32 ISA ARM Segment user
08:14:19.438(2)-0488 Control: 10c5383d Table: 1082406a DAC: 00000055
//Process.不,定是该process的错误,只是发生错误时,刚好在运行该process
//Stacks 08:14:19.446(2)-0488 Process syste«i_server(pid: 488, stack limit= 0xccf78218)
(21S.101827] 08:14:19.454(2)-0488 Stack: 0xccf79e38(Oxccf79d7。 to 0xccf7a08Q)- par(0xcf796d4)
---[ end trace 45d55384id6a0974 ]--- Kernel panic not syncing: Fatal exception
[217.359794] 08:14:21.712(0)-0488
解决方案: kernel异常一般找芯片原厂协助分析。
1、查看当前系统的CPU,IO等参数,输入top、iotop命令:(如:iotop-s io-m 9)
如果有异常飙高的进程,kill掉后会发现系统恢复正常。
之前项目上遇到过某些U盘IO性能比较差,媒体中心又在后台扫描媒体问题,导致系统各种卡顿,io wait时间比较长。
2、系统进程卡住,触发Watchdog:ps–A|grep system_server,一般而言,system_server正常的进程号是200多,如果发现进程号变成几千,则可能出现重启,结合tombstone和/data/anr下的trace文件分析重启原因
3、当前应用出现卡顿,造成ANR。输入logcat| grep ANR,如果有ANR打印,再去/data/anr下面查看相应进程的traces文件
有时在应用里面操作卡顿,按键响应延迟,但是却没有生成ANR,此时如果退出该应用(如果无法退出,在抓取足够信息的情况下,可以串口直接kill掉卡顿的应用),则一切正常,可能是应用自身实现问题,或者调用了其它接口导致(例如曾遇到应用调用了中间件、mediaplayer某些接口导致操作严重卡顿,按键响应延迟),这种情况则需应用和相应接口的实现者去排查。
1,串口无响应,大概率kernel panic,
2,串口日志狂输出,把系统堵塞,优化日志输出,关注关闭后压测。
3,Input系统完全堵塞,导致任何输入都无响应。
三、android性能跟踪分析工具系列- GPU 呈现模式分析
ps:喜欢的点赞哦 android性能跟踪分析工具系列-目录
找到一篇GPU呈现模式中基础概念解释最浅显易懂的,大家看完这篇再看下面的内容会好很多
GPU呈现模式分析这是 android手机自带的工具,先来看看这个工具:
上图中下面的红线,绿线就是我们想要的了,先别着急,下面就会细细说来
这个使用起来很简单的,打开 Android手机设置-开发者选项- GPU呈现模式分析,然后我们想分析哪个 app,哪个页面直接打开就好了,下面直接就会我们想要的数据图标,是不是很方便,嗯嗯,简单的才是最好的
每种分析工具为外乎监控和分析数据,GPU呈现模式分析工具又可以获取什么信息呢:
这个工具其实是最好用的了,很早就出现了,而且google一直在维护,更新,增强。仔细看这个工具有点如下优势:
经验丰富的程序员通过这个工具就可以大前提查看出 app哪里跑的慢了,看颜色条就知道,结合状况就可以有的放矢的结合其他工具去仔细查找了。
GPU呈现模式分析工具最核心的就是了解每种颜色代表什么任务,android 6.0之后,改工具得到加强,颜色条变得更多,其实我们查看起来还是看原来那些任务
我在本系列文章的理论简介中说到了渲染一帧的过程:
我们现在再来看数据图,从下往上看,先是蓝色的 update部分,蓝色执行的内容说白了就是执行有变动 view的 measu/ layout/ onDraw方法,然后生成一帧新的纹理。然后是紫色的 XFer部分,传递 cpu刚刚计算出来的这一帧给 GPU。然后红色的 Execute部分是 android的2D渲染器通知 GPU去绘制图形。最后黄色的 Process部分是 CPU等待 GPU通知绘制完成
更详细或者英文好的可以去看官方的文档
http://android.xsoftlab.net/tools/performance/profile-gpu-rendering/index.html
哈哈,我的手机就是6.0的,我就偷懒用最上面个的效果图啦
6.x中的图中,把颜色分的更新了,页更能表现出更多的任务来,仔细看最底下的深绿色新添加的,是我们需要仔关注的,表示 UI线程因为任务多,造成渲染界面延迟。其他的都是 4.x- 5.x版本的东西。
关于红色和黄色部分,这2部分的任务都不是在 UI线程执行的,都是在渲染线程或是 GPU了来干的,所以红的和黄的耗时不一定就是表示界面卡顿了,我们要根据情况区别分析:比如列表中有大量的网络图片需要加载显示,因为这些网络图片都是使用单独线程来加载显示的,所以这个 UI线程并不卡顿,但是要是我们加载大量 app内部的 png静态图片的话,那么肯定会卡的。
举个例子,我们有100个东西需求显示,我们在初始帧时只显示10个,然后1S内显示剩下的90个,这就相当于把100个东西放宽在1S内显示完。要是我们要求这100个东西一定要在初始帧显示完,那么这么大的计算和渲染量肯定会卡帧的。
所以我们在面临有大量 app内静态 png图片显示时,可以对 imageview做一下延迟显示,在页面显示之后,再去显示图片。
蓝色和绿色部分是我们需要重点关注的,这是因为布局层级多,效率低,过度绘制,造成的。另外图片量大,体积大也会造成浅蓝色耗时。
深绿色也是我们关注的重点,我在上面说了,这是新增的内容,反应的是 UI线程渲染界面出现延迟,要是发现这里耗时了,肯定是 cpu在这个时间段干的事多了,卡了,我们可以使用 Trace View去最终下在页面的生命周期函数内有耗时操作。
关于android性能分析工具到此分享完毕,希望能帮助到您。