技术复核(2026-10-13):本文原写于 2015 年。Systrace 的事件时间线仍有参考价值,Eclipse / Device Monitor 入口已过期;旧脚本参数以下文核对的 AOSP
android-5.0.0_r1为准。新增命令以 Android 11 / API 30 及以上的 Perfetto 为例,旧系统差异另列。后续文章见 Android Perfetto 系列目录。
| 旧流程 | 现在的对应方式 |
|---|---|
| Eclipse / Device Monitor 的 Systrace 按钮 | Android 9 / API 28 起可用设备端 System Tracing;也可通过 ADB 采集 |
systrace.py 调用 atrace 并生成 HTML |
Perfetto 采集命令生成二进制 trace;具体事件由类别或配置文件决定 |
| 浏览器直接打开旧 HTML | 使用 Perfetto UI 导入 trace,也可用 Trace Processor 做 SQL 分析 |
| 把 user 构建理解为不能采集 | user 构建可以采集系统 trace;可见数据取决于系统、数据源、应用配置与厂商策略 |
本文是Android性能优化工具系列的第一篇,这个系列主要介绍Android性能优化过程中会使用到的一些工具,以及如何用这些工具来发现问题和解决问题。在性能优化方面,Android有不少性能工具供大家来使用,按照我们一贯地 “发现问题-解决问题”的思路来看,发现问题才是最主要的,一上来就想着如何去解决问题,反而会事倍功半。
这一篇先来简单介绍一下Systrace这个工具。
Systrace 简单介绍
Systrace 随 Android 4.1 / SDK Tools R20 推出,是系统事件跟踪与可视化工具。它把 CPU 调度、SurfaceFlinger、WindowManager、View 等已启用的事件放到同一条时间线上,帮助开发者寻找系统行为之间的关系。它不会自动采样每一个 Java 方法,也不等于完整调用栈分析器。当年的 SDK Tools R20 公告
旧流程主要由三部分组成:
- 内核事件:依赖内核已启用的 ftrace 功能和可访问的事件。调度、I/O、频率等类别的可用性要在设备上确认。
- 用户态标记与采集:系统组件通过 ATrace 写入标记,
atrace配置类别并读取跟踪数据。应用添加自己的区间可使用android.os.Trace.beginSection()/endSection();这组公开 API 从 Android 4.3 / API 18 才提供,不是从 Android 4.1 就能直接调用。 - 主机端报告:旧
systrace.py通过 ADB 调用设备的 atrace,处理数据并生成带查看器的 HTML。采集已有系统事件不要求先修改应用代码;只有自定义业务区间需要相应埋点。
当前 Perfetto 还能接入更多数据源,不能把它的全部功能概括为 ftrace 封装。android.os.Trace 的标记仍可被 Perfetto 读取,接口说明见 Trace 和 Perfetto ATrace 文档。
Systrace 简单使用
无论采用哪种工具,基本顺序都一样:先准备目标页面,开始采集,在设备上重现操作,停止并保存 trace,再确认目标事件是否真的包含在文件里。文件生成成功并不等于已经采到了问题发生的那段时间。
旧图形界面入口(已过期)
下面保留原工具的位置,方便阅读历史资料。Android Device Monitor 已在 Android Studio 3.1 弃用、3.2 移除。
- Eclipse:进入 DDMS perspective,在 Devices 中选择设备,再点击 Systrace 按钮设置采集选项。
- 早期 Android Studio:通过 Tools → Android → Monitor 打开 Device Monitor,选择设备后点击 Systrace。
- 独立 Device Monitor:运行旧 SDK tools 目录里的
monitor,操作与上面相同。这些按钮不属于当前 Android Studio。
现在可以在设备的开发者选项中打开 System Tracing。Android 9 的设备端输出是 Systrace .ctrace;Android 10 / API 29 起输出 Perfetto 格式。选择需要的类别,开始录制、重现操作、停止后取出文件即可。
命令行使用:Perfetto
我更推荐命令行:配置好一次,后面重复抓取就方便多了。下面以 Android 11 / API 30 及以上、ADB 已连接且授权的设备为例。先查看设备支持的类别,再选择要采集的内容:
1 | adb shell atrace --list_categories |
采集命令运行的 10 秒内,在手机上执行待测操作,等命令结束后再 pull。如果某个类别不可用,按设备返回的列表调整。-b 64mb 设置 Perfetto 的环形缓冲区容量,不能把它当作旧脚本 -b 的 KB 参数或最终文件大小保证。多设备连接时,为每条 ADB 命令加上同一个 adb -s 设备序列号。
这属于 Perfetto 的简化模式,主要配置 ftrace / atrace;它不会自动启用所有数据源。例如需要 FrameTimeline 时,还要单独配置对应数据源。参数说明见 Perfetto CLI。
Perfetto 从 Android 9 就包含在系统中,但 Android 9 / 10 的部分设备需要先启用 tracing service;Android 9 的文件拉取权限也与新版本不同。旧机应先查 Android 采集兼容说明,不要把上面的完整流程直接套到所有版本。
应用自定义事件
要包含应用的 ATrace 标记,可以指定应用进程名。默认主进程通常与包名相同;多进程应用需要确认实际进程。例如:
1 | adb shell perfetto -t 10s -b 64mb -a com.example.app \ |
-a 选择要启用的应用标记,不会替应用自动插入方法追踪。应用中必须已有框架、库或业务代码的 Trace 调用,并满足系统版本的可追踪条件。例如 Android 10 / 11 的 user 系统上,应用通常需要 debuggable,或在 <application> 内声明 API 29 引入的 <profileable android:shell="true" />。性能对比应优先使用合适的 profileable release 构建,避免把 debug 构建的额外开销当成线上表现。见 profileable 的版本与权限说明。
同步区间的 beginSection() 与 endSection() 必须在同一线程配对且正确嵌套,通常用 try/finally 保证结束。一个区间的持续时间也可能包含等待和被抢占的时间,不应直接称作 CPU 执行时间。
旧 Systrace 命令(Android 5.0 源码版本)
下面保留历史脚本的使用方法,按 AOSP android-5.0.0_r1 的 systrace.py 核对。它使用 Python 2 语法及同目录的报告资源,不能只下载单个脚本就假定能运行。SDK 曾把它放在 platform-tools/systrace 等位置;当前安装是否包含该目录,要以实际文件为准。
在包含脚本与配套资源的旧工具目录中执行:
1 | python2 systrace.py --list-categories |
这里的 Python 2 只用于说明旧环境,不建议为了新设备采集去恢复过期解释器。现有 HTML 可以直接导入 Perfetto UI;不要依赖旧 HTML 内嵌查看器在新版 Chrome 中仍然正常工作。Perfetto 支持的外部格式
旧脚本的常见选项如下。它们属于上述脚本版本,不是 perfetto 参数表:
| 参数 | 作用 |
|---|---|
-h, --help |
查看脚本帮助 |
-o FILE |
输出 HTML,未指定时使用 trace.html |
-t N, --time=N |
采集 N 秒;此 Android 5.0 组合未指定时沿用 atrace 的 5 秒默认,其他版本应查帮助 |
-b N, --buf-size=N |
传递给 atrace 的缓冲区 KB 设置;对应内核每 CPU 缓冲区,最终报告大小还受 CPU 数量、事件和压缩影响 |
-k FUNCTIONS, --ktrace=FUNCTIONS |
选择逗号分隔的内核函数;能否使用取决于设备内核和权限 |
-l, --list-categories |
列出连接设备可用的类别 |
-a NAMES, --app=NAMES |
启用指定应用进程的标记,名称用逗号分隔 |
--from-file=FILE |
从已有的压缩 trace 输入生成报告;不是给任意文件改后缀 |
--link-assets, --asset-dir=DIR |
控制旧报告的 CSS / JavaScript 资源引用与目录 |
-e SERIAL, --serial=SERIAL |
选择 ADB 设备 |
缓冲区的每 CPU 含义见 Linux ftrace 文档,5 秒默认值见 Android 5.0 atrace.cpp。
常见类别有 gfx、view、wm、am、input、sched、freq、idle。原文还列出 membus、load、sync、workq 等旧设备类别,它们并非所有版本都具备;dalvik 这个历史名称也不能用来判断设备仍使用 Dalvik 而非 ART。先运行 --list-categories,比复制一长串未知标签更可靠。
保存旧命令别名
如果仍维护匹配的旧环境,可以在 Bash / Zsh 中保存别名。先把变量里的示例路径换成实际路径,再加载配置:
1 | SYSTRACE_SCRIPT='/path/to/legacy/systrace.py' |
别名赋值的 = 两侧不能有空格,引号必须是 shell 可识别的直引号。上面的类别仍须设备支持。输出使用 .html,既方便识别,也不会误以为改成 .Trace 就改变了文件格式。参数不用一次就记住,先把要看的事件抓下来,后面边分析边用,慢慢就熟悉了。
关于我 && 博客
下面是个人的介绍和相关的链接,期望与同行的各位多多交流,三人行,则必有我师!
- 博主个人介绍 :里面有个人的微信和微信群链接。
- 本博客内容导航 :个人博客内容的一个导航。
- 个人整理和搜集的优秀博客文章 - Android 性能优化必知必会 :欢迎大家自荐和推荐 (微信私聊即可)
- Android性能优化知识星球:付费社群已于 2026 年停止运营,不再招收新成员;此处保留历史介绍。
一个人可以走的更快 , 一群人可以走的更远
