Android性能优化工具:Systrace
一、Systrace概述
Systrace是一个平台提供的工具,可以记录设备活动。它将来自Android
内核的数据(例如CPU调度
程序,磁盘活动和应用程序线程)组合起来生成一个报告。该报告可帮助您改善您的应用或游戏的性能。
Systrace报告如图所示:
Systrace.png
此报告提供了Android设备在给定时间段内的系统进程的总体情况。该报告还检查捕获的跟踪信息,以突出显示它所观察到的问题,例如UI 卡顿或高功耗
Systrace工具不会收集有关应用程序进程中代码执行的信息。有关应用程序正在执行的方法以及它使用的CPU资源的更多详细信息,请使用Android Studio中的CPU Profiler。您还可以 使用CPU Profiler 生成跟踪日志并导入和检查它们。
二、在命令行上捕获
systrace
命令调用Systrace工具,该工具能够在系统级别收集所有进程的运行数据。
下面介绍如何从命令行生成Systrace报告。
要运行systrace
,请完成以下步骤:
systrace
命令在Android SDK Tools包中提供,位于android-sdk/platform-tools/systrace/
。
要为app生成HTML报告,您需要使用以下语法从命令行运行systrace
:
$ python systrace.py [options] [categories]
例如,使用以下命令记录设备活动并生成一个名为mynewtrace.html
的报告
$ python systrace.py -o mynewtrace.html
若没指定任何类别或者选项,systrace 会生成一份报告,包括所有可用的种类,同时使用默认的设置。
通用的选项
通用选项 | 描述 |
---|---|
-h 或 - -help | 显示帮助信息 |
-l 或 --list-categories | 列出所连设备可用的 tracing 种类 |
$ 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
pdx - PDX services
sched - CPU Scheduling
freq - CPU Frequency
idle - CPU Idle
disk - Disk I/O
sync - Synchronization
memreclaim - Kernel Memory Reclaim
binder_driver - Binder Kernel driver
binder_lock - Binder global lock trace
命令和命令选项
命令和选项 | 描述 |
---|---|
-o file | 将 trace 的网页报告写到指定的文件中。若未指定该选项,systrace 会保存报告至与 systrace.py 相同的目录下,同时命名 trace.html |
-t N 或 - -time=N | Trace 设备活动的 N 秒时间。若未指定该选项,命令行中,通过敲 Enter 回车键来终止 trace 进程 |
-b N 或 - -buf-size=N | 使用 N 千字节的 trace 缓冲区大小。这个选项可以限制在 trace 期间总共收集数据的大小 |
-k functions 或 - -ktrace=functions | Trace 指定内核方法的活动,指定于逗号分隔的列表 |
-a app-name或 - -app=app-name | 追踪应用包名,用逗号分隔 |
--from-file=file-path | 从一份文件里创建交互式的网页报告,如从包括原始 trace 数据的 TXT 文件,而不是运行着动态的 trace |
-e device-serial或 - -serial=device-serial | 根据设备的 serial number,在指定连接的设备上执行 trace |
categories | 指定跟踪的类型,例如gfx 用于呈现图形的系统进程。 |
三、设备上捕获
Android 9 (API level 28)或更高版本的手机设备上会有一个App可以调用系统的tracing,这个app跟systrace
命令行的功能相似。
系统的 Tracing app 允许你使用快捷设置记录system trace或者再app内使用菜单设置
(1)开启快捷设置
开启快捷设置.png如果您是第一次在测试设备上使用system trace,或者如果在设备的“ 快速设置”面板中没有看到 录制跟踪记录,请完成以下设置步骤:
- 启用开发者选项
- 打开开发者选项设置界面
- 在
调试
部分选择系统跟踪
将会打开System Tracing app - 在app设置页面中,开启
显示快捷设置图块
,录制跟踪记录
的图块将会出现在上面的设置面板中
System Tracing app.png
(2)使用System trace App捕获trace
- 点击
录制跟踪记录
快捷按钮
录制跟踪记录.png -
录制完成后点击通知栏停止跟踪
停止录制.png - 点击通知栏后会弹出分享
(3)使用ADB下载报告
可以使用ADB从设备中提取系统跟踪。将记录跟踪的设备连接到开发计算机,然后在终端窗口中运行以下命令:
cd /path-to-traces-on-my-dev-machine && \
adb pull /data/local/traces/ .
通过ADB导出的报告文件是.ctrace
文件,可以通过命令生成HTML报告
systrace --from-file trace-file-name .ctrace
三、自定义trace
Android 4.3 (API level 18) 以及更高版本可以使用 Trace
类中的方法来添加自定义trace
注意:当beginSection()被调用多次时,endSection()仅结束最近调用的 beginSection()方法。因此,对于嵌套调用(例如以下代码段中的调用),请确保每个beginSection()与 endSection()成对调用。此外,不能调用beginSection()一个线程并从另一个线程结束它; 你必须在同一个线程上调用这两个方法。
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Trace.beginSection("MyAdapter.onCreateViewHolder");
MyViewHolder myViewHolder;
try {
myViewHolder = MyViewHolder.newInstance(parent);
} finally {
// In try and catch statements, always call "endSection()" in a
// "finally" block. That way, the method is invoked even when an
// exception occurs.
Trace.endSection();
}
return myViewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Trace.beginSection("MyAdapter.onBindViewHolder");
try {
try {
Trace.beginSection("MyAdapter.queryDatabase");
RowItem rowItem = queryDatabase(position);
dataset.add(rowItem);
} finally {
Trace.endSection();
}
holder.bind(dataset.get(position));
} finally {
Trace.endSection();
}
}
}
四、Systrace报告
Systrace会产出一个HTML报告
(1) 快捷键
分析trace.html图形信息之前,先了解下快捷键 点击浏览器界面上右上角“?”,可以查看到各个快捷键提示
- 导航
导航操作 | 作用 |
---|---|
w | 放大,[+shift]速度更快 |
s | 缩小,[+shift]速度更快 |
a | 左移,[+shift]速度更快 |
d | 右移,[+shift]速度更快 |
- 快捷操作
常用操作 | 作用 |
---|---|
f | 放大当前选定区域(放大选定的一块) |
m | 标记当前选定区域(可以显示时间长度) |
v | 高亮****VSync****(所在的一帧) |
g | 切换是否显示60hz的网格线(同上) |
0 | 恢复trace到初始态,这里是数字0而非字母o(缩小到初始) |
h | 切换是否显示详情 |
/ | 搜索关键字 |
enter | 显示搜索结果,可通过← →定位搜索结果 |
` | 显示/隐藏脚本控制台 |
? | 显示帮助功能 |
(2) trace图结构
- Kernel
(上图为四核CPU)显示每个CPU各自执行的系统方法或自定义trace块,以及占据的时间长度 - SurfaceFlinger
surfaceFilnger,进程id为118,显示系统方法以及占据的时间长度 - com.android.janktown
应用进程,进程id为13409,显示应用进程内各个线程等信息
每个线程有颜色表示各自不同的状态:
灰色
:正在休眠。
蓝色
:可运行(它可以运行,但是调度程序尚未选择让它运行)。
绿色
:正在运行(调度程序认为它正在运行)。
红色
:不可中断休眠(通常在内核中处于休眠锁定状态)。可以指示 I/O 负载,在调试性能问题时非常有用。
橙色
:由于 I/O 负载而不可中断休眠。
(3) 审查帧和警告
报告中列出了渲染 UI 帧的每个进程,显示了时间线里每幅渲染的帧。绿色帧圈的表明,在要求的 16.6 毫秒内保持稳定的 60 帧/秒渲染帧像;黄色或红色帧圈的表明,渲染帧像时花费了超过 16.6 毫秒。
注意,在 Android 5.0 (API level 21) 及更高的设备上,渲染帧像的工作被分隔于 UI 主线程和渲染线程。以前的版本,创建帧像的工作都在 UI 主线程完成。
点击帧圈可以高亮化,提供系统完成渲染帧像额外的信息,包括警告。它也展示渲染帧像时系统正在执行的方法,因此可以根据这些方法来找出 UI 卡顿的原因。选择有问题的帧,trace 报告下面会展示问题详情的一个 alert。
alert.png
上图中显示的Alert显示出卡顿的主要问题是在ListView回收和重新绑定中花费了太多的时间。其中有相关事件的链接可以解释更多关于系统在这段时间内正在做什么的事情。
要看 trace 中工具发现的 alert,以及设备触发每个警告的次数,可以点击右上边上的 Alerts tab。Alerts 栏可以显示 trace 里发生的每一个问题和它们导致卡顿的频次。
alert.png
若看到 UI 主线程中做了太多的工作,需要我们自己找出消耗 CPU 时间的那些方法,方法之一是在认为导致性能瓶颈的地方,添加 trace 标记,来查看 trace 中出现的调用方法。若不确定哪些方法或许导致 UI 主线程的瓶颈,使用 Android Studio 内置的 CPU profiler,或生成的 trace 日志,然后使用 Traceview 查看。