Claw 分析 Perfetto Trace

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.34ms Binder:585_5 PowerManagerService.acquireWakeLockInternal
0.13ms InputDispatcher Message.recycleUnchecked
0.10ms Binder:585_5 MessageQueue.enqueueMessage
0.04ms Binder:585_5 MessageQueue.enqueueMessage
0.03ms RenderThread MessageQueue.nativeWake

3.3 主线程锁竞争

等待时间 持有者 阻塞位置
0.13ms InputDispatcher Message.recycleUnchecked
0.03ms RenderThread MessageQueue.nativeWake
0.01ms RenderThread MessageQueue.enqueueMessage
0.005ms Binder:585_5 WindowManagerService.addWindow
0.001ms InputDispatcher MessageQueue.enqueueMessage

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


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

操作 次数 平均耗时 最大耗时 总耗时
animator 15 101.16ms 134.78ms 1517.41ms
traversal 77 11.41ms 69.99ms 878.69ms
draw 75 11.00ms 69.95ms 825.05ms
animator:scaleX 1 350.60ms 350.60ms 350.60ms
animator:scaleY 1 350.56ms 350.56ms 350.56ms
binder reply 51 5.97ms 21.12ms 304.64ms
HIDL::IComposerClient::executeCommands 49 6.08ms 21.09ms 298.07ms
rcCompose encode 40 6.61ms 20.49ms 264.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_D 1313 0.12ms 14.18ms 153.28ms
HwBinder:347_3 1338 0.11ms 11.25ms 145.84ms
RenderThread 875 0.14ms 12.68ms 122.72ms
surfaceflinger 1381 0.08ms 30.48ms 113.32ms
kworker/1:2 117 0.91ms 51.49ms 106.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. 优化建议

立即执行

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

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

中期优化

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

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

9. 关键 SQL 查询

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

相关推荐
只会cv的小前端7 小时前
七巧低代码服务端脚本使用方法
android·低代码·rxjava
7 小时前
Android 自定义 View 实战:从零打造工业级全向摇杆控件(OmniJoystickView)
android·kotlin·自定义view·摇杆控件
雨白7 小时前
深入理解 Kotlin 协程 (十一):以逸待劳,探秘 select 多路复用与并发安全策略
android·kotlin
hunterandroid9 小时前
[Android 从零到一] Android 深度链接与 App Links:从 URI Scheme 到可验证的应用跳转
android
我命由我1234511 小时前
Jetpack Compose - Material Design 断点范围、WindowSizeClass、针对不同屏幕尺寸创建预览、四类导航栏
android·java·开发语言·java-ee·kotlin·android jetpack·android runtime
执明wa12 小时前
Android 开发中的设计模式入门:六大设计原则
android·设计模式
松仔log1 天前
Java中级——组合和继承
android·java·开发语言
我命由我123451 天前
Jetpack Compose - MaterialExpressiveTheme 与 MaterialTheme、ColorScheme
android·java·开发语言·java-ee·kotlin·android jetpack·android runtime
lilian2331 天前
Harmony os 技术实战|拼豆制图06:收藏 ID、生成记录与重启恢复怎么不打架
android·java·数据库·harmonyos
2601_955759621 天前
ClaudeAPI成本中心与业务标签设计指南
android·java·数据库