您可以使用 PerfettoSQL 和 Perfetto 标准库中的模块来查询 ProfilingManager 配置文件。由于 ProfilingManager 会对系统跟踪记录进行隐去处理,使其仅包含应用的进程数据,因此不支持依赖于其他进程的系统级标准库查询。不过,大多数应用范围内的查询和标准库模块无需修改即可正常运行。如需了解其他现成可用的查询,请参阅分析 Android 跟踪记录。
ProfilingManager 示例查询
直接使用以下示例查询,或将其用作您自己的 PerfettoSQL 分析的模板。
查找重复次数最多的切片
重复的切片通常表示存在冗余工作。如需详细了解函数语法,请参阅在 PerfettoSQL 中定义函数。以下查询定义了一个可重复使用的 PerfettoSQL 函数,该函数可查找与 GLOB 模式匹配的切片,并按频率对其进行排序:
-- You only need to call this once in the session to create or update the function
CREATE OR REPLACE PERFETTO FUNCTION find_duplicates(pattern STRING) RETURNS
TABLE(name STRING, count_slice LONG) AS SELECT name, COUNT(dur) as count_slice FROM slice WHERE name GLOB $pattern GROUP BY name HAVING COUNT(name) >= 2 ORDER BY count_slice DESC;
-- Subsequent calls can just use the function to find dupes
SELECT * FROM find_duplicates('*Text*')
卡顿查询
使用以下查询在系统跟踪记录中找出缓慢或卡顿的帧。
查找慢帧
此查询会查找渲染时间超过 16.6 毫秒 (60 Hz) 的帧。由于 Perfetto 以纳秒为单位存储切片时长,因此 dur 会与 16660000 进行比较:
INCLUDE PERFETTO module android.frames.timeline;
SELECT * FROM android_frames WHERE dur > 16660000;
查找导致卡顿的帧
此查询使用帧时间轴模块来查找应用根据设备的刷新率错过其渲染截止时间的帧:
INCLUDE PERFETTO module android.frames.timeline;
SELECT * FROM actual_frame_timeline_slice WHERE jank_type GLOB '*App Deadline Missed*';
查找重复次数最多的对象
在 Java 堆转储中,此查询会返回具有两个或更多实例的前 100 个类,以帮助您发现意外重复或缓存机会:
INCLUDE PERFETTO MODULE android.memory.heap_graph.heap_graph_class_aggregation;
SELECT * FROM android_heap_graph_class_aggregation WHERE obj_count >= 2
ORDER BY obj_count DESC LIMIT 100
冷启动延迟时间
此查询通过测量 bindApplication 与第一个 Choreographer#doFrame 切片之间的时长来估算冷启动到首帧时间 (TTFF):
-- This function finds slices that match the given GLOB $pattern
CREATE OR REPLACE PERFETTO FUNCTION find_slices(pattern STRING) RETURNS
TABLE (name STRING, ts LONG, dur LONG) AS
SELECT name,ts,dur FROM slice WHERE name GLOB $pattern;
-- This function generates a slice that starts at $startSlicePattern and finishes at the slice matched by $endSlicePattern. If $inclusive is true, then the end slice dur will be added, otherwise, the end slice start time will be used.
CREATE OR REPLACE PERFETTO FUNCTION generate_start_to_end_slices(startSlicePattern STRING, endSlicePattern STRING, inclusive BOOL) RETURNS
TABLE(name STRING, ts LONG, dur LONG) AS
SELECT name, ts, MIN(startToEndDur) as dur
FROM
(SELECT S.name as name, S.ts as ts, E.ts + IIF($inclusive, E.dur, 0) - S.ts as startToEndDur
FROM find_slices($startSlicePattern) as S CROSS JOIN find_slices($endSlicePattern) as E
WHERE startToEndDur > 0)
GROUP BY name, ts;
-- Using these functions we can estimate cold startup time by generating a slice between bindApplication and first frame.
SELECT * from generate_start_to_end_slices('bindApplication','*Choreographer#doFrame [0-9]*', true)