Claw 分析 Perfetto Trace

16 阅读3分钟

Perfetto Trace 分析报告

Trace 文件: trace_file.perfetto-trace
分析时间: 2026-05-12 12:13
分析工具: trace_processor_shell


1. 执行摘要

指标结果评级
掉帧率18.31%🔴 严重
锁竞争次数11 次🟡 中等
主线程长阻塞816 次 (>5ms)🔴 严重
最大单帧耗时87.8ms🔴 严重

2. 帧渲染分析

指标数值
总帧数590
掉帧数108
掉帧率18.31%
平均帧耗时9.88ms
最大帧耗时87.8ms

60fps 标准下,帧耗时超过 16.67ms 即视为掉帧。当前掉帧率 18.31%,用户体验会有明显卡顿感。


3. 锁竞争分析

3.1 总体分布

指标数值
锁竞争次数11 次
总等待时间6.67ms
平均等待0.61ms
最大等待6.34ms

3.2 严重锁竞争详情(Top 5)

等待时间持有者阻塞位置
6.34msBinder:585_5PowerManagerService.acquireWakeLockInternal
0.13msInputDispatcherMessage.recycleUnchecked
0.10msBinder:585_5MessageQueue.enqueueMessage
0.04msBinder:585_5MessageQueue.enqueueMessage
0.03msRenderThreadMessageQueue.nativeWake

3.3 主线程锁竞争

等待时间持有者阻塞位置
0.13msInputDispatcherMessage.recycleUnchecked
0.03msRenderThreadMessageQueue.nativeWake
0.01msRenderThreadMessageQueue.enqueueMessage
0.005msBinder:585_5WindowManagerService.addWindow
0.001msInputDispatcherMessageQueue.enqueueMessage

关键发现: 主线程多次被 RenderThread 和系统 Binder 线程阻塞,主要发生在 MessageQueue 操作上。


4. 主线程耗时分析(Top 10)

操作次数平均耗时最大耗时总耗时
animator15101.16ms134.78ms1517.41ms
traversal7711.41ms69.99ms878.69ms
draw7511.00ms69.95ms825.05ms
animator:scaleX1350.60ms350.60ms350.60ms
animator:scaleY1350.56ms350.56ms350.56ms
binder reply515.97ms21.12ms304.64ms
HIDL::IComposerClient::executeCommands496.08ms21.09ms298.07ms
rcCompose encode406.61ms20.49ms264.28ms

关键发现:

  • animator:scaleX/Y 单次耗时 350ms+,严重阻塞主线程
  • animator 操作平均 101ms,远超 16.67ms 帧预算

5. ANR 风险分析

指标数值
长阻塞次数 (>5ms)816 次
最短阻塞5.09ms
平均阻塞18.25ms
最大阻塞350.60ms

风险等级: 🔴 高
存在大量主线程阻塞事件,最大阻塞达 350ms,接近 ANR 阈值(5秒)。


6. CPU 调度分析(Runnable 等待 Top 5)

线程等待次数平均等待最大等待总等待
AudioOut_D13130.12ms14.18ms153.28ms
HwBinder:347_313380.11ms11.25ms145.84ms
RenderThread8750.14ms12.68ms122.72ms
surfaceflinger13810.08ms30.48ms113.32ms
kworker/1:21170.91ms51.49ms106.07ms

7. 根因总结

主要问题

  1. 动画性能问题 (最严重)

    • animator:scaleX/Y 单次执行 350ms+
    • 属性动画在主线程执行耗时操作
  2. 掉帧严重

    • 掉帧率 18.31%,远超健康标准 (<5%)
    • 最大单帧 87.8ms,是标准 16.67ms 的 5 倍
  3. 主线程阻塞

    • 816 次长阻塞事件
    • 被 RenderThread 和 Binder 线程频繁阻塞
  4. 锁竞争

    • MessageQueue 锁竞争频繁
    • PowerManagerService 锁单次阻塞 6.34ms

8. 优化建议

立即执行

1. 动画优化
   ├── 使用 ObjectAnimator.setDuration() 控制时长
   ├── 复杂动画使用 RenderThread (硬件加速)
   └── 避免在动画回调中执行耗时操作

2. 减少主线程阻塞
   ├── 将 scaleX/scaleY 动画移到子线程计算
   ├── 使用 Choreographer.postFrameCallback 替代频繁 post
   └── 减少 Binder 同步调用,改用异步

中期优化

3. 布局优化
   ├── 减少 View 层级,降低 traversal 耗时
   ├── 使用 ConstraintLayout 替代嵌套布局
   └── 避免在 onDraw 中创建对象

4. 锁优化
   ├── 减少跨线程 MessageQueue 操作
   ├── 使用 HandlerThread 隔离耗时消息
   └── 避免在动画期间触发 WakeLock 申请

9. 关键 SQL 查询

-- 查询掉帧详情
SELECT * FROM actual_frame_timeline_slice 
WHERE dur > 16666666 ORDER BY dur DESC;

-- 查询主线程长阻塞
SELECT * FROM __intrinsic_slice s
JOIN thread t ON s.track_id = t.utid
WHERE t.is_main_thread = 1 AND s.dur > 50000000;

-- 查询锁竞争
SELECT * FROM __intrinsic_slice 
WHERE name LIKE '%monitor contention%' ORDER BY dur DESC;

报告生成: Perfetto Trace Processor