Android应用冷启动分析-详解-Perfetto SQL

18 阅读2分钟

引言

在分析perfetto文件的时候,最直观的方式就是采用网页可视化分析:

ui.perfetto.dev/

image.png

将trace文件加载进来即可按照timeline进行分析:

image.png

实际上通过perfetto ui或者perfetto提供的trace_processor工具可以让我们来按照sql的形式来操作处理trace,通过下面的链接可以下载对应平台上的trace_processor文件:

github.com/google/perf…

image.png

下面基于perfetto ui来进行sql查询演示,实际上为了方便更多时候是在本地利用trace_processor搭配python来实现对trace文件实现自动化分析。

简介

slice表结构

首先我们需要明确perfetto trace文件里面都有哪些表以及基础表字段是什么,使用下面的sql语句进行查询:

SELECT * FROM pragma_table_info('slice');

image.png

这里slice是trace中最核心的表,其存储用户态事件比如代码打点、方法调用等,在trace中看到的所有信息都是基于slice打印的

所有表信息

使用下面的sql语句可以查看到所有的表信息:

SELECT name FROM sqlite_master WHERE type IN ('table', 'view') ORDER BY name;

image.png 同时在perfetto ui中也支持直接查看:

image.png

核心表

  • slice: 基础信息
  • thread_track: slice线程信息
  • thread: 线程信息
  • process: 进程信息

注: slice-thread_track使用track_id来join; thread_track-thread使用utid来join; thread-process使用upid来join;

  • args: slice参数
  • thread_state: 线程调度信息
  • sched_slice: 调度运行片
  • cpu: cpu信息

使用操作

sql查询思路

一般写trace sql会按照下面的思路来:

  1. 先宽后窄

首先使用like搜索名字,确认切片叫什么,然后再缩小事件窗,加入depth、线程名等。

  1. 先确定两端时间(start ts和end ts)再下钻

这个就需要了解关联调用链,比如说binder的transaction和replay。

  1. 过滤时长

将无用的时间端过滤掉,缩小范围。

  1. limit收窄slice信息

防止打印过多信息

实例

下面举几个例子:

  1. 查询高德地图最耗时的10个slice
SELECT 
    s.name AS slice_name,
    t.name AS thread_name,
    s.dur / 1e6 AS dur_ms
FROM slice s
JOIN thread_track tt ON s.track_id = tt.id
JOIN thread t ON tt.utid = t.utid
JOIN process p ON t.upid = p.upid
WHERE p.name = 'com.autonavi.minimap'
ORDER BY s.dur DESC
LIMIT 10;

image.png

  1. 查询各个线程在不同cpu上执行时间
SELECT
  process.name AS process_name,
  thread.name AS thread_name,
  cpu,
  sum(dur) AS cpu_dur
FROM sched
JOIN thread USING (utid)
JOIN process USING (upid)
GROUP BY
  process_name,
  thread_name,
  cpu
ORDER BY
  cpu_dur DESC
LIMIT 100;

image.png

  1. system_server线程运行时长拆解
SELECT 
    t.name AS thread_name,
    s.cpu,
    SUM(s.dur) / 1e6 AS cpu_dur_ms
FROM sched s
JOIN thread t USING (utid)
JOIN process p USING (upid)
WHERE p.name = 'system_server'
GROUP BY t.name, s.cpu
ORDER BY t.name, cpu_dur_ms DESC;

image.png