外观
打开 Perfetto 后,你怎样从一段长耗时找到真正瓶颈?
标准回答
我先对齐启动起终点,再沿关键路径逐段分析。长耗时要区分线程正在执行、可以运行但没被调度,以及等待锁、Binder 或 I/O。找到等待对象或实际执行热点后,才能判断是后台化、消除依赖,还是修复对端慢调用。
- 看请求进入、主线程初始化、布局和渲染、目标帧呈现等阶段,优先找影响目标终点的那一段。总 CPU 消耗大不一定影响首个响应。
- 主线程同步等待 Binder 时,要继续看服务端;处于 runnable 却没运行时关注 CPU 竞争;不能看到一条长 slice 就断言 Java 计算慢。
- 修改后对照同场景的 Trace,确认原瓶颈缩短、依赖变化符合预期,并检查是否把卡顿转移到首次点击。
通俗例子
若主线程某调用共占 100ms,其中大部分是等对端回复,单纯把附近的布局优化 10ms 仍解决不了主要问题。应继续查这次等待由谁触发、对端在等什么。
深入解释
**按阶段缩小范围:**看请求进入、主线程初始化、布局和渲染、目标帧呈现等阶段,优先找影响目标终点的那一段。总 CPU 消耗大不一定影响首个响应。
**沿等待关系找原因:**主线程同步等待 Binder 时,要继续看服务端;处于 runnable 却没运行时关注 CPU 竞争;不能看到一条长 slice 就断言 Java 计算慢。
**用相同口径复采:**修改后对照同场景的 Trace,确认原瓶颈缩短、依赖变化符合预期,并检查是否把卡顿转移到首次点击。
追问与回答
有渲染回调就代表上屏了吗?
应用提交绘制、合成和实际呈现是不同阶段,应结合该设备能提供的帧及显示信息判断。
如何证明就是这段代码?
用调用关联、补充打点和受控修改验证;时间靠近只能提供线索,不能单独证明因果。
易混淆点
不要把所有 sleeping 都叫锁等待,也不要把 FrameTimeline 等轨道视为每个版本必然具备。
进一步举证
- 准备一段脱敏 Trace 的口述路径:线程状态、关键 slice、等待对象。
- 准备一个修改前后的对照,而不只准备总耗时截图。
内容来源
- Android · AI Agent 知识手册 · 原条目
resume-R05