# Systrace/Perfetto全解读 ## 概述 Systrace和Perfetto是Android系统级性能分析工具,可以追踪系统调用、CPU调度、渲染流程等,是性能优化的必备工具。 ## Systrace基础 ### Systrace简介 Systrace是Android 4.1引入的系统级追踪工具,可以记录系统调用、CPU调度、渲染等信息。 ### 安装与使用 ```bash # Systrace位于Android SDK的platform-tools/systrace目录 # 或使用Python脚本 python systrace.py [options] [categories] # 基本用法 python systrace.py -t 10 -o trace.html sched gfx view ``` ### 常用参数 ```bash # -t: 追踪时间(秒) python systrace.py -t 10 -o trace.html # -o: 输出文件 python systrace.py -t 10 -o my_trace.html # -b: 缓冲区大小(KB) python systrace.py -t 10 -b 32768 -o trace.html # -a: 指定应用包名 python systrace.py -t 10 -a com.example.app -o trace.html # -k: 指定要追踪的函数(用逗号分隔) python systrace.py -t 10 -k load_symbols,unload_symbols -o trace.html ``` ### 追踪类别(Categories) ```bash # CPU调度 sched # 图形渲染 gfx # 视图系统 view # 输入事件 input # 磁盘I/O disk # 内存 mem # 活动管理器 am # 窗口管理器 wm # 数据库 db # 网络 network # 电源管理 power # 全部类别 -a ``` ### 完整示例 ```bash # 追踪应用启动 python systrace.py -t 5 -a com.example.app \ -o startup_trace.html \ sched freq idle am wm gfx view binder_driver hal dalvik camera input res # 追踪流畅度问题 python systrace.py -t 10 \ -o jank_trace.html \ gfx view sched freq idle # 追踪内存问题 python systrace.py -t 10 \ -o memory_trace.html \ sched freq idle mem ``` ## Perfetto基础 ### Perfetto简介 Perfetto是Google开发的下一代性能分析工具,从Android 9开始集成,功能更强大,支持更长的追踪时间。 ### 使用Perfetto #### 1. 通过Android Studio 1. 打开Android Studio 2. 连接设备 3. 打开Profiler 4. 选择CPU Profiler 5. 点击"Record"开始录制 6. 执行操作 7. 停止录制,查看结果 #### 2. 通过命令行 ```bash # 使用perfetto命令行工具 adb shell perfetto -c - --out /data/misc/perfetto-traces/trace # 或使用配置文件 adb shell perfetto -c /data/local/tmp/config.pb -o /data/local/tmp/trace.pb ``` #### 3. 通过Web UI ```bash # 1. 录制trace adb shell perfetto -c - --out /data/misc/perfetto-traces/trace # 2. 拉取trace文件 adb pull /data/misc/perfetto-traces/trace trace.pb # 3. 在 https://ui.perfetto.dev/ 打开 ``` ### Perfetto配置文件 ```protobuf # config.pb (文本格式) buffers: { size_kb: 63488 fill_policy: DISCARD } buffers: { size_kb: 2048 fill_policy: DISCARD } data_sources: { config { name: "android.surfaceflinger.frame" } } data_sources: { config { name: "linux.ftrace" ftrace_config { ftrace_events: "sched/sched_switch" ftrace_events: "sched/sched_waking" ftrace_events: "power/suspend_resume" ftrace_events: "power/cpu_frequency" ftrace_events: "power/cpu_idle" ftrace_events: "gfx/mali_gpu_total" buffer_size_kb: 2048 drain_period_ms: 250 } } } duration_ms: 10000 ``` ## Trace文件分析 ### 1. 打开Trace文件 ```bash # Systrace HTML文件 # 直接在浏览器中打开 trace.html # Perfetto文件 # 在 https://ui.perfetto.dev/ 打开 # 或使用Android Studio打开 ``` ### 2. 关键指标 #### Frame信息 - **绿色**: 正常帧(< 16.67ms) - **黄色**: 轻微掉帧(16.67-33.33ms) - **红色**: 严重掉帧(> 33.33ms) #### CPU信息 - **CPU频率**: 查看CPU是否降频 - **CPU使用率**: 查看CPU负载 - **CPU调度**: 查看线程调度情况 #### 渲染信息 - **VSYNC**: 垂直同步信号 - **Choreographer**: 帧调度 - **RenderThread**: 渲染线程 - **GPU**: GPU渲染时间 ### 3. 分析技巧 #### 查找卡顿 1. 找到红色或黄色的Frame 2. 点击Frame查看详细信息 3. 查看该时间段内的CPU活动 4. 查找耗时操作 #### 分析启动时间 1. 找到应用启动的起点 2. 追踪到首帧渲染完成 3. 分析各个阶段的耗时 4. 识别瓶颈 #### 分析内存问题 1. 查看内存分配事件 2. 查找频繁的GC 3. 分析内存增长趋势 ## 实战案例 ### 案例1:分析应用启动 ```bash # 1. 录制启动trace python systrace.py -t 5 -a com.example.app \ -o startup.html \ sched freq idle am wm gfx view # 2. 分析步骤 # - 找到Application.onCreate开始时间 # - 找到MainActivity.onCreate开始时间 # - 找到首帧渲染完成时间 # - 计算各阶段耗时 ``` **关键指标**: - Application初始化时间 - Activity创建时间 - 布局inflate时间 - 首帧渲染时间 ### 案例2:分析流畅度问题 ```bash # 1. 录制流畅度trace python systrace.py -t 10 \ -o jank.html \ gfx view sched freq idle # 2. 分析步骤 # - 找到掉帧的Frame(红色/黄色) # - 查看该Frame的耗时 # - 分析主线程活动 # - 查找阻塞操作 ``` **常见问题**: - 主线程阻塞 - 布局复杂 - 过度绘制 - 内存抖动 ### 案例3:分析CPU使用率 ```bash # 1. 录制CPU trace python systrace.py -t 10 \ -o cpu.html \ sched freq idle # 2. 分析步骤 # - 查看CPU频率变化 # - 查看CPU使用率 # - 分析线程调度 # - 查找CPU密集型操作 ``` ## 高级技巧 ### 1. 自定义Trace点 ```java // 在代码中添加自定义trace点 import android.os.Trace; // 开始trace Trace.beginSection("my_custom_section"); // 执行操作 doSomething(); // 结束trace Trace.endSection(); ``` ### 2. 异步Trace ```java // 异步trace Trace.beginAsyncSection("async_operation", cookie); // 执行异步操作 Trace.endAsyncSection("async_operation", cookie); ``` ### 3. 计数器 ```java // 设置计数器 Trace.setCounter("my_counter", value); ``` ### 4. 使用ATrace命令 ```bash # 在shell中启用trace adb shell setprop debug.atrace.tags.enableflags 0x1 # 开始trace adb shell atrace -t 10 -b 32768 gfx view sched > trace.txt # 停止trace adb shell atrace --async_stop ``` ## Perfetto高级功能 ### 1. 长时间追踪 ```bash # Perfetto支持更长的追踪时间 adb shell perfetto -c - --out /data/misc/perfetto-traces/trace # 可以追踪数小时 ``` ### 2. 多数据源 Perfetto支持同时追踪多个数据源: - CPU调度 - 内存分配 - 网络活动 - 电源管理 - 自定义事件 ### 3. SQL查询 Perfetto支持SQL查询trace数据: ```sql -- 查询所有Frame信息 SELECT * FROM slice WHERE name = 'Choreographer#doFrame'; -- 查询掉帧 SELECT * FROM slice WHERE name = 'Choreographer#doFrame' AND dur > 16666667; -- 查询CPU使用率 SELECT ts, cpu, value FROM counter WHERE name = 'cpu.freq'; ``` ## 性能优化建议 ### 1. 基于Trace的优化 1. **识别瓶颈**: 找到耗时最长的操作 2. **分析原因**: 理解为什么耗时 3. **制定方案**: 设计优化策略 4. **验证效果**: 再次录制trace对比 ### 2. 常见优化点 - **减少主线程工作**: 将耗时操作移到后台线程 - **优化布局**: 减少布局层级和复杂度 - **减少GC**: 避免内存抖动 - **优化算法**: 使用更高效的算法 ### 3. 持续监控 - 建立性能基线 - 定期录制trace - 设置性能告警 - 跟踪性能趋势 ## 工具对比 | 特性 | Systrace | Perfetto | |------|----------|----------| | 支持版本 | Android 4.1+ | Android 9+ | | 追踪时间 | 较短 | 较长 | | 数据源 | 有限 | 丰富 | | 分析能力 | 基础 | 强大 | | SQL查询 | 不支持 | 支持 | | Web UI | 基础 | 强大 | ## 最佳实践 1. **明确目标**: 在录制前明确要分析的问题 2. **合适时长**: 选择适当的追踪时间 3. **关键类别**: 只追踪相关的类别 4. **多次录制**: 多次录制确保结果一致 5. **对比分析**: 优化前后对比分析 ## 相关链接 - [[README]] - [[06-性能优化体系/流畅度(Choreographer+VSYNC)]] - [[06-性能优化体系/启动优化方法论]]