一、简介
Systrace 是平台提供的旧版命令行工具,可记录短时间内的设备活动,并保存在压缩的文本文件中。该工具会生成一份报告,其中汇总了 Android 内核中的数据,例如 CPU 调度程序、磁盘活动和应用线程。
我们一般使用Systrace分析如下性能问题:
- UI卡顿掉帧
- 启动慢
- 异常线程
Android 10 中引入了全新平台级跟踪工具Perfetto。这是适用于 Android、Linux 和 Chrome 的更加通用和复杂的开源跟踪项目。与 Systrace 不同,它提供数据源超集,以protobuf 编码的二进制流形式记录任意长度的跟踪记录。
二、抓取Systrace
通过Android Device Monitor抓取Systrace
这种方式比较简单,直接从DDMS中打开配置即可
- Destination File :制定生成的trace.html文件的地址
- Trace duration:抓取时间,通常设置5秒,并在5秒内重现问题,时间太短会导致问题重现时没有被抓到,时间太长会导致JavaHeap不够而无法保存。因此在能抓到问题点的情况下,时间越小越好。
- Trace Buffer Size:存储Systrace的size,同样太小会导致信息丢失,太长会导致Java Heap不够而无法保存。如果检测结果有异常,请调整Buffer Size的大小试试。
- Enable Application Traces from:检测的应用,默认选择none,这里需选择自己需要检测的应用。
- Commonly Used Tag:常用标签,这部分TAG全部使能。只关注显示情况的话 ,只选取Graphics和View System即可。
- Advanced Options:高级选项。如果设备root了,可以看到更多的TAG,如eMMC commands、Synchonization、Kernel Workqueues。
通过Python命令抓取Systrace
systrace.py脚本位于:sdk路径/platform-tools/systrace/systrace.py
注意:要运行此脚本必须安装 jdk1.8 和 python2.7,其他版本亲测不支持。
python命令:
python systrace.py [options] [categories]
参数分为两部分
- options — 命令参数
- categories — 感兴趣的系统模块,如不指定categories,则默认包含所有可用项
例如,我们抓一个10秒的systrace:
python systrace.py --time=10 -o mynewtrace.html
options可取值:
options | 解释 |
-o <File> | 指定trace数据文件的输出路径,如果不指定就是当前目录的trace.html |
-t N, --time=N | 执行时间,默认5s。绝对不要把时间设的太短导致你操作没完Trace就跑完了,这样会出现Did not finish 的标签,分析数据就基本无效了 |
-b N, --buf-size=N | buffer大小(单位kB),用于限制trace总大小,默认无上限 |
-k <KFUNCS>,--ktrace=<KFUNCS> | 追踪kernel函数,用逗号分隔 |
-a <APP_NAME>,--app=<APP_NAME> | 这个选项可以开启指定包名App中自定义Trace Label的Trace功能。也就是说,如果你在代码中使用了Trace.beginSection("tag"), Trace.endSection;默认情况下,你的这些代码是不会生效的,因此,这个选项一定要开启 |
--from-file=<FROM_FILE> | 从文件中创建互动的systrace |
-e <DEVICE_SERIAL>,--serial=<DEVICE_SERIAL> | 指定设备,在特定连接设备上进行跟踪,由设备序列号标识 。 |
-l, –list-categories | 这个用来列出你分析的那个手机系统支持的Trace模块,一般来说,高版本的支持的模块更多 |
categories可取值:
$ python systrace.py -l gfx - Graphics input - Input view - View System webview - WebView wm - Window Manager am - Activity Manager sm - Sync Manager audio - Audio video - Video camera - Camera hal - Hardware Modules res - Resource Loading dalvik - Dalvik VM rs - RenderScript bionic - Bionic C Library power - Power Management pm - Package Manager ss - System Server database - Database network - Network adb - ADB vibrator - Vibrator aidl - AIDL calls nnapi - NNAPI rro - Runtime Resource Overlay pdx - PDX services sched - CPU Scheduling irq - IRQ Events irqoff - IRQ-disabled code section tracing preemptoff - Preempt-disabled code section tracing i2c - I2C Events freq - CPU Frequency idle - CPU Idle disk - Disk I/O mmc - eMMC commands sync - Synchronization workq - Kernel Workqueues memreclaim - Kernel Memory Reclaim regulators - Voltage and Current Regulators binder_driver - Binder Kernel driver binder_lock - Binder global lock trace pagecache - Page cache memory - Memory gfx - Graphics (HAL) ion - ION allocation (HAL)
windows环境可能报的错误
(1)ImportError: No module named win32con
解决方案:下载并安装对应版本的pywin32库:https://github.com/mhammond/pywin32/releases
这里选择:pywin32-227.win-amd64-py2.7.exe
(2)ImportError:No module named 'six’
解决方案:
- 下载six安装文件:https://pypi.python.org/pypi/six/
- 解压并放到python安装目录的Scripts文件夹下
- 执行安装命令:python setup.py install
三、分析Systrace
systrace报告可以清楚地看到每个时间点各个线程的运行情况
报告分析快捷键:
按键操作 作用 w 放大,[+shift]速度更快 s 缩小,[+shift]速度更快 a 左移,[+shift]速度更快 d 右移,[+shift]速度更快 f 放大当前选定区域 m 标记当前选定区域 v 高亮VSync g 切换是否显示60hz的网格线 0 恢复trace到初始态,这里是数字0而非字母o h 切换是否显示详情 / 搜索关键字 enter 显示搜索结果,可通过← →定位搜索结果 ` 显示/隐藏脚本控制台 ? 显示帮助功能
以卡顿为例分析报告:
我们在Frames一行中可以看到很多"F",每一个"F"就是一帧,测量两帧之间的间隔
- 如果大于16.7ms,则该帧达不到60fps帧率,会卡顿,用黄色或红色标注
- 如果小于16.7ms,则该帧可以达到60fps帧率,不会卡顿,用绿色标注
我们可以看到这个报告中有一个红色"F",放大测量与附近的"F"间隔约为50ms,帧率只有20fps,明显有卡顿。点击上面对应的Alerts,可以看到一些修改建议:
这里的卡顿并不是其他异常线程造成的,是我们UI太复杂造成渲染慢,我们需要精简UI。
Systrace报告所包含的信息是进程级别的,我们无法定位到具体的引起卡顿的代码。如果要更进一步分析,我们需要在代码中可疑的地方添加trace log,使用TraceView工具来具体分析。
Trace.beginSection("defined by yourself"); //开始跟踪 Trace.endSection(); //结束跟踪