Skip to content
阅读进度

打开 Perfetto 后,你怎样从一段长耗时找到真正瓶颈? ​

返回 性能与稳定性 目录

标准回答 ​

我先对齐启动起终点,再沿关键路径逐段分析。长耗时要区分线程正在执行、可以运行但没被调度,以及等待锁、Binder 或 I/O。找到等待对象或实际执行热点后,才能判断是后台化、消除依赖,还是修复对端慢调用。

  • 看请求进入、主线程初始化、布局和渲染、目标帧呈现等阶段,优先找影响目标终点的那一段。总 CPU 消耗大不一定影响首个响应。
  • 主线程同步等待 Binder 时,要继续看服务端;处于 runnable 却没运行时关注 CPU 竞争;不能看到一条长 slice 就断言 Java 计算慢。
  • 修改后对照同场景的 Trace,确认原瓶颈缩短、依赖变化符合预期,并检查是否把卡顿转移到首次点击。

通俗例子 ​

若主线程某调用共占 100ms,其中大部分是等对端回复,单纯把附近的布局优化 10ms 仍解决不了主要问题。应继续查这次等待由谁触发、对端在等什么。

深入解释 ​

**按阶段缩小范围:**看请求进入、主线程初始化、布局和渲染、目标帧呈现等阶段,优先找影响目标终点的那一段。总 CPU 消耗大不一定影响首个响应。

**沿等待关系找原因:**主线程同步等待 Binder 时,要继续看服务端;处于 runnable 却没运行时关注 CPU 竞争;不能看到一条长 slice 就断言 Java 计算慢。

**用相同口径复采:**修改后对照同场景的 Trace,确认原瓶颈缩短、依赖变化符合预期,并检查是否把卡顿转移到首次点击。

追问与回答 ​

有渲染回调就代表上屏了吗? ​

应用提交绘制、合成和实际呈现是不同阶段,应结合该设备能提供的帧及显示信息判断。

如何证明就是这段代码? ​

用调用关联、补充打点和受控修改验证;时间靠近只能提供线索,不能单独证明因果。

易混淆点 ​

不要把所有 sleeping 都叫锁等待,也不要把 FrameTimeline 等轨道视为每个版本必然具备。

进一步举证 ​

  • 准备一段脱敏 Trace 的口述路径:线程状态、关键 slice、等待对象。
  • 准备一个修改前后的对照,而不只准备总耗时截图。

内容来源 ​

用完整回答理解机制,用真实证据解释项目。