ProfilingManager プロファイルをクエリする

ProfilingManager プロファイルのクエリは、通常の Perfetto プロファイルのクエリと似ています。プロファイルのクエリ方法については、PerfettoSQL のスタートガイドをご覧ください。

通常の Perfetto トレースと ProfilingManager トレースの重要な違いは、ProfilingManager トレースがトレース リダクタを通過することです。このリダクタは、プライバシー上の理由から、アプリに関係のない他のプロセスに関する情報を削除します。

Perfetto 標準ライブラリの一部のクエリは、秘匿化されたトレースでは使用できません。これは、ProfilingManager がアプリのプロファイリング データのみを収集し、他のプロセスのプロファイリング データは収集しないためです。その結果、ProfilingManager で使用できるクエリは、ローカル Perfetto を使用して記録された完全なシステム プロファイルのクエリよりも少なくなります。

クエリ空間は縮小されますが、Perfetto 標準ライブラリの多くの PerfettoSQL クエリとテーブルをそのまま使用できるため、ぜひお試しください。

また、Android トレースの分析を確認して、変更を加えずに有用なパフォーマンス データを提供する、すぐに使用できるクエリを見つけることをおすすめします。

ProfilingManager のサンプルクエリ

クエリの作成を簡素化するため、このセクションでは ProfilingManager で動作するクエリのリストを示します。これらのクエリを直接使用することも、他のクエリを作成するための例として使用することもできます。

最も重複しているスライスを見つける

このクエリは、トレース内の重複するスライスを検索し、出現頻度で並べ替えて、最も重複しているスライスを最初に表示します。

重複した作業を見つけることは、トレースで不要な作業を見つける一般的な方法です。

-- You only need to call this once in the session to create the function
DROP TABLE IF EXISTS find_duplicates;
CREATE 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*')

ジャンククエリ

遅いフレームを見つける

このクエリは、想定されるフレームレートが 60 Hz(16.6 ミリ秒)であると仮定して、アプリがフレームの生成に時間がかかりすぎているフレームを検索します。Perfetto テーブルのスライス期間はナノ秒単位で保存されるため、dur は 16,660,000 に設定されています。

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 = 'App Deadline Missed';

このクエリは、アプリがフレームの生成に時間がかかりすぎるためにトレースでジャンクが発生する場所を見つけるのに役立ちます。これは、UI スレッドがフレームの生成に失敗したことを意味します。極端な状況では、ANR の前に発生することがあります。

重複が最も多いオブジェクトを見つける

ヒープダンプなどのメモリ関連のプロファイルをクエリして、より複雑なメモリ分析を行うこともできます。

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

このクエリは、重複するオブジェクトの上位 100 件を返します。これにより、複数回インスタンス化されたオブジェクトを特定できます。これは、オブジェクトをキャッシュに保存する機会を明らかにしたり、意図しない重複を特定したりするのに役立ちます。

コールド スタートアップ レイテンシ

スタートアップをクエリすることもできます。このセクションでは、トレースでコールド スタートアップ時間を推定するための、より詳細なクエリについて説明します。

-- This function finds slices that match the given GLOB $pattern
CREATE OR REPLACE 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)

このクエリは、起動時間を定義する 2 つのスライス(bindApplication(通常はコールド アプリ起動の開始時に見つかります)と最初の Choreographer#doFrame スライス(最初に生成されたフレーム))の間の時間を表すスライスを生成します。この指標は、コールド スタートアップの TTFF(最初のフレームまでの時間)を効果的に推定します。