Android性能系列专题理论之十:systrace/perfetto相关指标知识点细节含义总结

【关注我,后续持续新增专题博文,谢谢!!!】

上一篇我们讲了:

这一篇我们开始讲:

目录

一、问题时间点确定

[二、Activity 启动时间确认](#二、Activity 启动时间确认)

三、前台进程确认方式

四、binder信息格式解析

五、亮灭屏信息

补充中......


一、问题时间点确定

Perfetto 文件命名规则

Perfetto 生成的跟踪文件通常遵循以下命名规则:

  1. 默认命名规则

    Perfetto 默认生成的跟踪文件通常以 trace 开头,后跟时间戳或其他唯一标识符,时间戳为抓取该perfetto 文件结束时的时间。。例如:

    • trace_20230412_123456.perfetto-trace
    • trace_<timestamp>.perfetto-trace
  2. 自定义命名规则

    用户可以通过命令行或配置文件指定输出文件名。例如:

    复制代码
    perfetto --txt -c config.pbtxt -o custom_name.perfetto-trace

    此时文件名为 custom_name.perfetto-trace

  3. Android 设备上的命名规则

    在 Android 设备上,Perfetto 生成的跟踪文件通常存储在 /data/misc/perfetto-traces/ 目录下,文件名可能包含以下信息:

    • 时间戳(如 trace_20230412_123456.perfetto-trace
    • 会话 ID(如 trace_session_123.perfetto-trace
  4. 文件扩展名

    Perfetto 跟踪文件的扩展名通常为 .perfetto-trace.pftrace

问题发生的时间确定

  1. 通过时间戳定位问题

    Perfetto 跟踪文件包含高精度的时间戳,可以通过以下方式确定问题发生的时间:

    • 在 Perfetto UI 中打开跟踪文件,查看事件的时间轴。
    • 使用 perfetto --query 命令查询跟踪文件中的时间范围。
  2. 跟踪文件元数据

    Perfetto 跟踪文件包含元数据,记录跟踪的开始和结束时间。可以通过以下命令查看:

    复制代码
    perfetto --query -i trace.perfetto-trace

    输出中会包含 trace_start_timetrace_end_time

  3. 事件时间戳

    在 Perfetto UI 中,可以选中特定事件查看其时间戳。时间戳通常以纳秒或微秒为单位,可以转换为可读时间格式。

  4. 与其他日志关联

    将 Perfetto 跟踪文件的时间戳与系统日志或其他日志文件的时间戳对齐,可以更精确地定位问题发生的时间。

  5. 时间同步

    确保设备或系统的时钟与 Perfetto 跟踪文件的时间戳同步,避免因时间偏差导致定位错误。


Pefertto 中 start time 的计算方式

通过 slice 表查询

执行以下 SQL 查询可以直接获取指定 slice 的时间信息:

复制代码
SELECT * FROM slice WHERE id = 28852;

查询结果包含 ts(时间戳,单位为纳秒)和 dur(持续时间),可以通过转换获取绝对时间或相对时间。

通过 surfaceflinger 主线程事件获取

onMessageRefresh 是 SurfaceFlinger 主线程的关键事件,其时间戳可直接反映刷新周期。在 Perfetto 中可以通过以下方式定位:

  1. 在 UI 界面选择 surfaceflinger 进程的主线程(通常为 com.android.surfaceflinger)。
  2. 查找 onMessageRefresh 事件的 ts 字段,该值为系统绝对时间(纳秒级)。
时间戳转换

若需将纳秒时间戳转换为可读格式(如 Unix 时间戳或日期时间),可使用以下方法:

  • Python 示例

    复制代码
    import datetime
    timestamp_ns = 123456789000  # 替换为实际 ts 值
    timestamp_s = timestamp_ns / 1e9
    print(datetime.datetime.fromtimestamp(timestamp_s))
注意事项
  • Perfetto 的时间戳基于系统启动时钟(CLOCK_BOOTTIME),需注意与 UTC 时间的偏移。
  • SurfaceFlinger 的刷新事件通常以 VSYNC 信号为基准,onMessageRefresh 的时间可能包含帧调度延迟。

systrace 时间戳与内核时间的对应关系

systrace 工具生成的时间戳(TIMESTAMP)基于内核时钟源,通常与内核日志(kernel log)中的时间记录存在直接关联。内核日志的时间标记可能采用 UTC 格式或其他本地时区格式,需通过以下方式建立对应关系:


内核日志中查找时间对应关系

  1. 定位关键事件

    在 systrace 输出中选取具有明确特征的事件(如进程调度、中断触发),记录其 TIMESTAMP 值。

  2. 搜索内核日志

    在 kernel log 中使用 grep 或工具过滤相同事件的日志行,例如:
    dmesg | grep "特定事件关键词"

  3. 时间格式转换

    若内核日志使用 UTC 时间,需将其转换为本地时间戳以便对比。例如通过 date -d "@$(timestamp)" 转换 Unix 时间戳。


验证时间同步性

  • 时钟源检查

    确认内核时钟源与 systrace 的时钟源一致(如 clocksource 设置为 tsckvm-clock)。可通过以下命令查看:
    cat /sys/devices/system/clocksource/clocksource0/current_clocksource

  • 时间偏移校准

    若存在固定偏移,可能是时区或系统启动时间差异导致。可通过计算 systrace 与内核日志中同一事件的时间差进行校准。


示例操作流程

  1. 从 systrace 中提取事件 A 的 TIMESTAMP:123456.789
  2. 在内核日志中搜索事件 A 的 UTC 时间:[2023-01-01T00:00:00.000] Event A occurred
  3. 将 UTC 时间转换为 Unix 时间戳:date -d "2023-01-01T00:00:00.000" +%s.%N
  4. 比较转换后的 Unix 时间戳与 systrace TIMESTAMP,确认偏移量。

注意事项

  • 确保内核日志的时钟未被频繁调整(如 NTP 同步可能导致跳跃)。
  • 高精度时间对比需启用内核的 CONFIG_PRINTK_TIMECONFIG_PRINTK_TIME_FULL 配置选项。

二、Activity 启动时间确认

systrace 查看应用启动时间

通过 systrace 可以分析应用的启动时间,特别是从 system_server 的 launching 行获取关键指标。这些数据在 ActivityMetricsLogger.java 文件中记录,包含冷启动、热启动、温启动的具体时间信息。


启动时间指标说明

ActivityMetricsLogger.java 文件中输出的启动时间指标分为以下三类:

  1. 冷启动时间

    应用进程不存在,系统需要创建新进程并初始化 Activity。时间包括进程创建、加载资源和初始化组件。

  2. 热启动时间

    应用进程已存在,Activity 仍在内存中。时间仅包括恢复 Activity 到前台的过程。

  3. 温启动时间

    应用进程存在但 Activity 被销毁,需要重建 Activity。时间包括恢复进程状态和重建 Activity。

三、前台进程确认方式

前台进程识别方法

通过 Event Log 分析

wm_on_resume_called 标记表示目标 Activity 被唤醒到前台,wm_on_paused_called 标记表示目标 Activity 退到后台。检查 Component Name 对应的 Activity 状态变化。

检查应用进程的输入事件

在目标应用进程中搜索 deliverInputEvent 相关 Trace。Android 事件机制会将输入事件派发给获得焦点的应用,前台应用通常存在此类 Trace。

分析 System Server 事件队列

system_serverInputDispatcher 中检查输出队列事件数量:

  • 输入事件通过 InputChannelInputDispatcher 传递到应用端 ViewRootImpl.java
  • 排除干扰项:ExInputReceiverPointerEventDispatcher0swipe-upColorSideGestureright 等非前台应用。
检查 System Server 焦点应用信息

ActivityTaskManagerService.java 中查找 Focused app: 相关 Trace。该信息在 Activity 执行 resume 后打印,直接反映当前前台应用。

跟踪应用主线程状态

在目标应用主线程 Trace 中查找 PerformResumePerformPause 标签:

  • 两个标签之间的时间段可认定为应用处于前台状态。
  • 需结合 Activity 生命周期日志验证准确性。
使用 BatteryHistorian 工具

通过功耗分析工具 BatteryHistorian 的 Top app 泳道数据:

  • 直观展示用户在不同时间段切换的应用。
  • 适合长时间跨度的前台应用行为分析。

四、binder信息格式解析

binder调用日志格式解析

日志格式分为两种模式:请求模式(P->)和响应模式(N<-),具体结构如下:

请求模式

复制代码
P->*,*,*

响应模式

复制代码
N<-*,*,*

字段含义说明

第一字段:调用方向标识

  • P:表示进程发起binder请求(客户端调用服务端)
  • N:表示进程响应binder请求(服务端返回结果)
  • <-:符号固定存在,表示数据传输方向(请求发出或结果返回)

第二字段:接口描述符

  • 采用索引化设计,将高频调用的binder接口转换为数字标识
  • 目的是减少日志数据量,提升传输效率
  • 实际接口名称需要通过索引表转换还原

第三字段:传输类型标识

  • 0:表示BLOCKING阻塞式传输(同步调用)
  • 1:表示ONEWAY非阻塞传输(异步调用)

第四字段:事务代码

  • 对应AIDL文件中定义的方法编号
  • 首方法固定编号为0,后续方法按声明顺序递增
  • 例如:AIDL中第3个定义的方法对应Code=2

典型示例分析

复制代码
P->42,1,0

表示:客户端发起异步调用(ONEWAY),调用接口索引42对应的方法,事务代码为0(首方法)

复制代码
N<-16,0,3

表示:服务端同步返回结果,处理的是接口索引16的请求,事务代码为3(第4个方法)

技术实现说明

  1. 索引优化机制通过维护高频接口映射表实现
  2. ONEWAY标识位决定是否等待服务端返回
  3. 事务代码与AIDL方法定义顺序严格对应
  4. 该日志格式由Onetrace模块在系统底层植入

五、亮灭屏信息

systrace 查看屏幕状态的方法

通过 systrace 分析 system_server 进程的 DisplayPowerMode 行可以获取屏幕状态信息。具体方法如下:

查看 DisplayPowerMode 行

  • 在 systrace 结果中定位 system_server 进程。
  • 查找 DisplayPowerMode 行,该行会显示屏幕状态的实时变化。
  • 状态值对应关系:
    • 状态如下: public static final int POWER_MODE_OFF = 0;

      public static final int POWER_MODE_DOZE = 1;

      public static final int POWER_MODE_NORMAL = 2;

      public static final int POWER_MODE_DOZE_SUSPEND = 3;

      public static final int POWER_MODE_ON_SUSPEND = 4;

搜索 setDisplayState TAG

  • 在 systrace 中搜索 setDisplayState 标签。
  • 该标签同样会显示屏幕状态变化,数值含义与 DisplayPowerMode 一致:
    • 0:灭屏
    • 1:亮屏
    • 2:解锁

注意事项

  • 确保 systrace 抓取时包含 system_server 进程和 Display 相关标签。
  • 结合其他系统事件(如输入事件、WakeLock)分析,可以更准确判断屏幕状态切换的上下文。

扩展应用

  • 通过分析状态切换的时间点,可以定位亮灭屏延迟或异常问题。
  • 结合 CPU 频率、线程调度等信息,可进一步优化功耗或性能问题。

补充中......

【关注我,后续持续新增专题博文,谢谢!!!】

下一篇讲解:

相关推荐
Truffle7电子3 小时前
STM32CubeIDE/Programmer/Touch GFX 应用
stm32·单片机·嵌入式硬件
constant_LDX4 小时前
步进电机开发(一、硬件设计)
单片机·嵌入式硬件
北山有鸟4 小时前
修改源码法和插件法
嵌入式硬件·学习
richxu202510014 小时前
嵌入式学习之路->stm32篇->(14)通用定时器(上)
stm32·单片机·嵌入式硬件·学习
Deitymoon4 小时前
STM32——串口通信(USART)
单片机·嵌入式硬件
iCxhust4 小时前
微机原理实践教程(C语言篇)---A002流水灯
c语言·开发语言·单片机·嵌入式硬件·51单片机·课程设计·微机原理
techdashen6 小时前
从 51% CPU 占用到 SIMD 加速:Cloudflare 防火墙引擎的性能优化实录
性能优化
Deitymoon6 小时前
STM32——外部中断按键控制led
stm32·单片机·嵌入式硬件
czwxkn6 小时前
7STM32(stdl)flash内部闪存
stm32·单片机·嵌入式硬件