EN

Android Perfetto 系列 3:熟悉 Perfetto View

字数统计: 4.1k阅读时长: 15 min
2024/05/21
loading

本篇是 Perfetto 系列文章的第三篇,前两篇介绍了 Perfetto 是什么以及 Perfetto Trace 怎么抓,本篇主要是在网页端打开 Perfetto Trace 之后,面对复杂的 Perfetto 信息该怎么看。

Android 官方将 Systrace 列为 legacy 工具,并推荐在 Android 10 及以上使用 Perfetto。写下本文时,Perfetto 在我的日常工作中已基本取代 Systrace,我接触到的 OPPO、vivo 团队也在迁移,因此用这个系列继续介绍如何观察 Android 系统。

技术核查:2026-10-14。 保留 2024 年界面与案例截图,快捷键和分析语义按官方文档及 v58.3(11fbaed83636)源码补充。原始案例 Trace 未随文提供,图中的唤醒链和数值不当作新版本实测结果。

本文目录

Paul Graham 说:要么给大部分人提供有点想要的东西,要么给小部分人提供非常想要的东西。Perfetto 属于小部分人非常想要的东西,那就开始写吧,欢迎大家多多交流和沟通,发现错误和描述不准确的地方请及时告知我,我会及时修改,以免误人子弟。

我想借这个系列,和大家一起对照 Perfetto 看 App、Framework、Linux 是怎么配合起来运行的。如果读过不少源码和性能文章,还是记不住流程,不妨把代码放回 Trace 的时间线上看看。

Perfetto 系列目录

  1. Android Perfetto 系列目录
  2. Android Perfetto 系列 1:Perfetto 工具简介
  3. Android Perfetto 系列 2:Perfetto Trace 抓取
  4. Android Perfetto 系列 3:熟悉 Perfetto View
  5. Android Perfetto 系列 4:使用命令行在本地打开超大 Trace
  6. Android Perfetto 系列 5:Android App 基于 Choreographer 的渲染流程
  7. Android Perfetto 系列 6:为什么是 120Hz?高刷新率的优势与挑战
  8. Android Perfetto 系列 7:MainThread 和 RenderThread 解读
  9. Android Perfetto 系列 8:深入理解 Vsync 机制与性能分析
  10. Android Perfetto 系列 9:CPU 信息解读
  11. Android Perfetto 系列 10:Binder 调度与锁竞争
  12. Android Perfetto 系列 11:PerfettoSQL、Trace Processor 与回归检测
  13. Android Perfetto 系列 12:Trace 数据流与丢失排查
  14. Android Perfetto 系列 13:Perfetto SDK、Track Event 与 App 现场 Trace
  15. Android Perfetto 系列 14:heapprofd 与内存 Profiling
  16. Android Perfetto 系列 15:Boot Trace、长时间现场 Trace 与偶发问题抓取
  17. Android Perfetto 系列 16:GPU、Power Counters 与硬件瓶颈分析
  18. Android Perfetto 系列 17:专项场景自动化、问题清单与平台体系
  19. Android Perfetto 系列 18:响应速度实战,从输入事件到首帧反馈
  20. 视频(B站) - Android Perfetto 基础和案例分享
  21. 视频(B站) - Android Perfetto 分享 - 出图类型分享:AOSP、WebView、Flutter + OEM 系统优化分享

如果大家还没看过 Systrace 系列,下面是传送门:

  1. Systrace 系列目录 : 系统介绍了 Perfetto 的前身 Systrace 的使用,并通过 Systrace 来学习和了解 Android 性能优化和 Android 系统运行的基本规则。
  2. 个人博客 :个人博客,主要是 Android 相关的内容,也放了一些生活和工作相关的内容。

欢迎大家在 关于我 页面了解微信群入口,讨论你的问题、你最想看到的关于 Perfetto 的部分,以及跟各位群友讨论所有 Android 开发相关的内容

Perfetto View 界面

抓到 Trace 后,可在 Perfetto UI 打开。官方 record_android_trace 脚本默认会拉取文件并打开浏览器;使用 --no-open 时则不会。下图是 2024 年首页,Legacy UI 等入口不能当作当前版本仍有的承诺。

Perfetto View 界面

可以点击 Open trace file,或把 Trace 拖进页面。大文件可能受浏览器内存限制,可用本地 Trace Processor 配合 UI。

Perfetto Trace 界面

打开 Perfetto Trace 之后界面如下:

Trace 操作区

按旧截图,界面大致分为四个区域;新版本可能调整菜单名称和位置:

  1. 最左边的操作区:这里最主要的是 Current Trace 这一栏下面的那几个会经常用到。
    1. Show timeline :显示当前 Trace,切到了别的界面之后,再点这个就会回到 Trace View 界面
    2. Query:写 SQL 查询语句和查看执行结果的地方
    3. Metrics:预先定义的分析入口,并非所有 Trace 都有完整指标;需要对应数据源和版本支持。
    4. Info and stats:检查 Trace 元信息、解析统计与数据丢失提示。先确认采集是否覆盖问题时段。
  2. 上方的信息和操作区域:最主要就是看时间。
  3. 中间的 Trace 内容区:展示调度、频率、线程埋点等轨道。是否出现 Input、Binder、Memory 或帧信息取决于采集内容。本文沿用旧图的 Task 叫法时,主要指线程的一段状态或执行区间;调度 Running 与函数 slice 不同,后者可能包含等待,不能把色块时长都算成 CPU 时间。
  4. 最下方的信息区:展示选中事件的详情、范围统计或查询结果。Android Logs 需要采集日志数据,应用打印过日志不等于 Trace 已包含它;Ftrace events 同样受采集配置限制。

Perfetto 界面最初看的时候会觉得很乱,花里胡哨的,但是用习惯了之后,真香~

基本操作

我在当时的环境中,打开约 500 MB Trace 的体验比 Systrace 顺滑。但加载和交互速度还受事件数量、类型、查询、浏览器及主机内存影响,500 MB 不是性能保证或文件大小上限。

常用操作仍是 W/S 缩放、A/D 左右平移、单击选择事件。新版可按 ? 查看当前快捷键,用 Ctrl+Shift+P(macOS 为 Cmd+Shift+P)打开命令面板。快捷键在时间轴获得焦点时使用,不要在 SQL 输入框里触发。下面三张是旧版帮助图,尤其 SQL 页入口和组合键应以当前提示为准,参见官方 UI 指南。

基本操作

SQL 相关的操作

其他快捷键

其他快捷键里面用的比较多的:

  1. f 是放大选中

  2. M:按当前选择创建临时区间注释。v58.3 使用同一个临时注释 ID,再按 M 会替换它;从单个事件创建时还会形成范围选择。Esc 清除选择,不应等同于删除注释。参见Notes 实现。

    配图

  3. Shift+M:每次创建一个新的区间注释,不会像 M 那样替换上一个,适合同时标注多个区间。“持续”只指这种保留方式,不表示已经把注释写回原始 Trace 文件。

    配图

    选择注释对应的范围后可查看统计。下图里的 SUM(dur) 是 slice 时长汇总,父子 slice 可能重复覆盖时间;thread_dur 为 null 也不等于 CPU 时间为 0。
    配图

  4. 删除持续 Mark

    1. 点击区间注释的边缘标记,选中注释。
    2. 旧版在下方 Current Selection 中操作。
    3. 点击 Remove;v58.3 也提供 Remove selected note 命令(默认 Delete)和 Notes & markers 管理入口。
      配图
  5. q :隐藏和显示信息 Tab,由于 Perfetto 非常占屏幕,熟练使用 q 键很重要,看的时候快速打开,看完后快速关闭。

  6. 插旗子:Perfetto 还可以通过插旗子的方法来在 Trace 上做标记,Perfetto 支持你把鼠标放到 Trace 最上面,就会出现一个旗子,点击左键即可插一个旗子在上面,方便我们标记某个事件发生,或者某个时间点

配图

  1. 取消插的旗子:与退出持续选中一样,点击旗子,右下角有个 Remove ,点击就可以把这个旗子干掉了,就不插图了

Perfetto 使用技巧

查看唤醒源

这里的“唤醒源”是线程从等待转为可运行时记录的 waker,不是设备从休眠唤醒的电源原因,也不直接说明锁持有者或完整业务依赖。需要有调度/唤醒事件;缺失记录、IRQ 上下文或 Trace 边界都可能使链路不完整。

在 Android Systrace 响应速度实战 3 :响应速度延伸知识 这篇文章中,有讲 Systrace 如何查看唤醒源。相比 Systrace,Perfetto 中查看唤醒源更直接:

下面分别示范主线程和 RenderThread 的唤醒查看方式,注意每张图里实际选中的线程名称。

点击 Runnable 状态

选中线程状态轨道的 Runnable 区间后,可在 Related thread states 查看关联。第一张图实际选中的是主线程 scrollingexample,waker 是 SurfaceFlinger 的 app 线程,不是 RenderThread。Runnable 也可能来自抢占,不能要求每一段都有一次新的外部唤醒。

  1. Waker:本次记录到的唤醒线程/状态;它是继续排查的线索。
  2. Previous state:这个 Task 的前一个状态
  3. Next state:这个 Task 的后一个状态
    配图

点击他上方的 Running 状态,查看连续唤醒信息

选中线程状态里的 Running 区间,可通过详情中的 CPU 链接跳到对应调度切片,再查看它前面的 Runnable 与唤醒事件。不要把紧邻或重叠的另一个线程直接当作 waker。

点击 RenderThread 上方的 Running 状态,通过小箭头跳转到 CPU Info 区域
配图

这张旧图显示所选 RenderThread 区间对应一次主线程唤醒;它不代表 RenderThread 的每次唤醒都来自主线程。
配图

这张旧图中,主线程的唤醒来源是 SurfaceFlinger 的 app 线程。下方 Scheduling latency 量的是从可运行到实际获得 CPU 的间隔,不是发送唤醒调用本身耗费的时间。
配图

查看 Critical Path(Task)

这里的 Critical Path 是 Perfetto 根据线程状态与唤醒关系重建的阻塞路径,用来寻找所选线程等待期间的相关活动。它不是所有依赖任务的并集,也不是自动证明的业务根因;未埋点的异步关系、数据缺失和 IRQ 上下文都会影响解释。

v58.3 的插件实现中,Critical path lite 主要显示状态路径;完整 Critical path 再叠加相关 slice 信息,这些嵌套 slice 不是自动采集的函数调用栈。唤醒图实现也注明 Android 14 之前可能缺少 IRQ 上下文,从而影响准确性。

旧版可选中 Running 状态后在下方点击 Critical path。v58.3 仍有 selected thread state slice 命令,但源码使用该线程和整份 Trace 的时间边界;若只分析一个窗口,应框选线程状态轨道,再用 over area selection 版本。
配图

稍等片刻就会出现我们选择的 MainThread 对应的 Critical path:

配图

这张旧图中,主线程等待结束前关联到了 SurfaceFlinger 的 app 线程。图上的 CPU 编号属于这个实例,不是固定调度规则。
配图

还可以向前检查 app 线程自己的 waker;原文提到的 TimerDispatch 关系没有展示对应截图,需要回到原始 Trace 核实,不能推广成所有帧都经过的固定链路。

这个视图把相关状态和埋点放在一起,便于继续检查等待原因;它本身不能证明优化某个线程就一定缩短端到端耗时。

Pin (固定到最上面)

点击轨道标题旁的 Pin 图标,可把关心的轨道固定到顶部。新版还可用工作区组织轨道,避免全部固定后挤占可视空间。

配图

比如下面是我 Pin 的从 App 到 SF 的流程图,放到一起的话就会清晰很多,看掉帧的话也会更方便。
配图

CPU Info 区域 Task 高亮

在 CPU Info 区域,鼠标放到某一个 Task 上,就会这个 Task 对应的 Thread 的其他 Task 都会高亮。

我们经常用这个方法初步看线程在哪些 CPU 上运行。它显示的是调度结果,不能单凭高亮或颜色判断迁移原因、核容量或完整调度策略。

配图

查看 Buffer 消耗情况

对于提交给 SurfaceFlinger 合成显示的图层,选择 App 的 Actual Timeline 切片可沿 flow 查对应显示帧。同进程多 Layer 时核对 Layer 名与 frame token;一条 flow 不是 BufferQueue 深度,也不证明某个 buffer 被完整复制了一次。FrameTimeline 数据需要 Android 12+ 并已启用采集。

配图

快速查看 App 执行超时

本节的“超时”指帧未按预期预算完成,不是 ANR。多缓冲可以让已有帧继续呈现,但不能据此排除新内容延迟或卡顿。

Expected Timeline 是预算,Actual Timeline 是实际帧处理区间,包含等待与 GPU 工作。结合 Present Type、On time finish、Prediction Type 与 Jank Type 判断,不要把每个长色块都当 CPU 超时。
配图

红色帧可帮助定位问题,但颜色不是完整原因。下图显示 App Deadline Missed、Late Present 与 Valid Prediction;仍需结合主线程、RenderThread 和 GPU 相关数据解释,不能只凭分类断定某个函数有错。参见FrameTimeline 文档。

配图

在 Perfetto 上查看 Log

采集了 android.log 数据后,可以在 Android Logs 中对齐日志时间与线程活动。旧图的悬停竖线只是时间定位,不证明日志对应的调用造成了该处阻塞。

配图

Ftrace events 可以查看已保留的原始事件;缺少条目可能来自未启用、设备不支持或丢失,不能直接理解为事件从未发生。

配图

分析 Thread 的 Running 信息

拖动框选时间窗口,并选中目标线程的状态轨道,可查看各状态的时长分布。只选 slice 轨道得到的是埋点统计,不能代替调度状态。单线程 Running 占比也不等于整机 CPU 利用率。分析 App 启动时,经常会用到这项统计。

做精确统计时应把每条状态区间裁剪到所选窗口,再按有效覆盖时长或窗口时长计算,并写明分母;未知/缺失不能补为 Sleep 或 0。下方旧截图的 Wall duration 合计约 865.44 ms,而 Selected range 为 857.5 ms,不能直接把表内数值当作该窗口的精确占比。

配图

从 UI 操作过渡到 SQL 自动化

本文介绍的是 Perfetto UI 的手工分析路径:看线程、看唤醒源、Pin 关键线程、框选区间、检查 FrameTimeline 和日志。这个阶段适合建立直觉,但不适合批量复盘。

当你已经能在 UI 里稳定找到问题点后,下一步应该把“我刚才看了什么”翻译成 SQL:

  1. 先确认所选事件的数据表和 SQL ID。slice 存放埋点区间,track、thread_track、process_track 描述轨道及归属,不是四种可互换的 Slice 表。
  2. 调度状态查 thread_state,CPU 上的运行区间查 sched / sched_slice;按同一时间窗口裁剪,区分墙钟时间、CPU 时间与未覆盖部分。
  3. 帧分析优先使用 FrameTimeline 表或标准库模块,核对 frame token、Layer、预测有效性和丢帧状态,不只数红块。
  4. track_id、utid、upid 用来关联轨道、线程与进程;它们本身不证明跨进程因果。Binder、Buffer、Camera 或 Audio 链路还需各自的事务、flow、帧 token 等关联证据。

这套从 UI 操作到 SQL 的过渡,第 11 篇有完整展开:Android Perfetto 系列 11:PerfettoSQL、Trace Processor 与回归检测。

总结

上面分享了 Perfetto 基本的界面和操作,以及分享了一些比较常用的 Perfetto 的技巧。Google 目前在积极推广和维护 Perfetto,很多新功能指不定哪天就蹦出来了,到时候觉得有用我也会更新上来。

至此 Perfetto 基础篇就结束了,后续就是通过 Perfetto 这个工具,来了解 Android 系统运行的基本流程,以及使用 Perfetto 以及 Perfetto SQL 来分析遇到的性能、功耗等问题。

关于我 && 博客

下面是个人的介绍和相关的链接,期望与同行的各位多多交流,三人行,则必有我师!

  1. 博主个人介绍 :里面有个人的微信和微信群链接。
  2. 本博客内容导航 :个人博客内容的一个导航。
  3. 个人整理和搜集的优秀博客文章 - Android 性能优化必知必会 :欢迎大家自荐和推荐 (微信私聊即可)
  4. Android性能优化知识星球 :2026 年已关闭,保留历史介绍。

一个人可以走的更快 , 一群人可以走的更远

微信扫一扫

CATALOG
  1. 1. 本文目录
  • Perfetto 系列目录
  • Perfetto View 界面
  • Perfetto Trace 界面
  • 基本操作
  • Perfetto 使用技巧
    1. 1. 查看唤醒源
      1. 1.1. 点击 Runnable 状态
      2. 1.2. 点击他上方的 Running 状态,查看连续唤醒信息
    2. 2. 查看 Critical Path(Task)
    3. 3. Pin (固定到最上面)
    4. 4. CPU Info 区域 Task 高亮
    5. 5. 查看 Buffer 消耗情况
    6. 6. 快速查看 App 执行超时
    7. 7. 在 Perfetto 上查看 Log
    8. 8. 分析 Thread 的 Running 信息
    9. 9. 从 UI 操作过渡到 SQL 自动化
  • 总结
  • 关于我 && 博客