プロファイル タイプとそれぞれの有用性

Android では、いくつかの種類のパフォーマンス プロファイルを記録できます。プロファイルを収集すると、アプリの実行速度、メモリ使用量、消費電力などに関連する問題をデバッグできます。

このドキュメントでは、最も有用なプロファイルの種類と、一般的なパフォーマンスの問題をデバッグするために各プロファイルをいつ使用するかについて説明します。

システム トレース

システム トレースの例
図 1.: システム トレースの例。

システム トレースは、プロセス、スレッド、タイミング情報、CPU とタスクの実行、システムまたはユーザー定義のイベントに関する情報を含む強力なプロファイルです。

アプリの観点から見ると、トレース内の情報の性質は、レイテンシ、ジャンク、メモリ、バッテリーなど、幅広い分野に及ぶ可能性があります。

システム トレースには、システム定義またはユーザー定義のいずれかである次のコード駆動型イベントが含まれます。コード駆動型イベントは、ユーザーが関数呼び出しを通じてトリガーできるイベントです。

  • トレース スライス: コード内の異なるポイント間の時間を表します。これらは、Trace.beginSection API と Trace.endSection API を使用して追加できます。
  • トレース カウンタ: 指標を表す数値(ヒープサイズなど)。Trace.setCounter API を使用して追加できます。

システム トレースには、PerfettoSQL クエリから作成できる指標も含まれており、分析の実行やトレースの比較に使用できます。

システム トレースを使用して次のタスクを行うことをおすすめします。

  • レイテンシの問題を診断します。システム トレースは、遅延、待機、スケジューリングの問題によるレイテンシの問題を見つけるのに最適です。サンプルベースのプロファイルなどの他のプロファイラでは、システム トレースが提供するタイミング情報は提供されません。

  • 重複する計算を見つけます。トレースを行うと、特定の計算が繰り返されているかどうかを確認できます。これは、不要なオペレーションを示している可能性があります。

  • ロックの競合の問題を診断します。リソースがブロックされたときにスレッドの状態とスライスに関する情報が表示されるため、ロック(synchronized ブロックなど)がユーザー ジャーニーの遅延の原因になっているかどうかを特定できます。

  • アプリのマルチスレッドを理解する。トレースには複数のスレッドのビューが表示され、各スレッドの状態と、システムまたはアプリによって追加されたトレース スライスが表示されます。このマルチスレッド ビューを使用すると、どのスレッドがアクティブか、スリープ状態か、何を実行しているか、どのように相互作用しているかを把握できます。

  • 複雑なパフォーマンス分析を実行します。強力なユーザー インターフェースとさまざまな種類の情報を表示する機能により、システム トレースはレイテンシ、メモリ、バッテリー使用量など、幅広いパフォーマンスの問題のデバッグに役立ちます。

システム トレースでは、PerfettoSQL を使用したクエリもサポートされています。この強力な機能により、次のことが可能になります。

  • 特定のデータを抽出します。
  • トレースデータをカスタム指標に変換します。
  • クエリからデバッグ トラックを作成して、Perfetto UI で最も重要な項目を簡単に可視化できるようにします。
  • Perfetto UI 内で複雑な分析を直接実行します。

スタック サンプル プロファイル

スタック サンプル プロファイルの例
図 2.: スタック サンプル プロファイルの例。

スタック サンプル プロファイルは、コード実行のサンプルを記録し、スレッドが CPU でタスクを実行している間、設定されたレートでコールスタック情報を保存することで機能します。これにより、実行中にコードが何をしているかについての分析情報が得られます。

スタック サンプルを使用して次のことを行うことをおすすめします。

  • ホットスポットを最適化します。スタック サンプルは、CPU アクティビティが多いコードの部分を特定するのに役立ちます。これは、スレッドが「実行中」状態であることが多いことを意味します。
  • コードの実行について理解する。スタック サンプルは、コードベースの全体的な動作を理解するのに役立ちます。
  • 実行すべきでないコードを特定します。実行されるはずのないコールスタックが見つかることがあります。これは、すぐに最適化できることを示しています。

ヒープダンプ

ヒープダンプの例
図 3.: ヒープダンプの例。

Java ヒープダンプには、アプリの Java ヒープメモリのスナップショットが表示されます。このスナップショットには、ダンプが取得された時点のすべてのオブジェクトと、それらのオブジェクトが互いに参照する方法が含まれます。

ヒープダンプを収集して、次のことを行うことをおすすめします。

  • 重複するオブジェクトを検出します。ヒープダンプにはライブ オブジェクトの数が表示されるため、重複したオブジェクトの追跡に役立ちます。また、オブジェクト参照も提供されるため、オブジェクトが作成されたコードの場所を特定できます。
  • メモリリークを見つける。ヒープダンプは、ダンプの取得時に使用されていないはずのメモリを明らかにし、メモリリークの可能性を示します。
  • 最適化できるオブジェクトを特定します。ヒープダンプは、大量のメモリを使用しているオブジェクトとその数を表示することで、非効率的なメモリ使用パターンを特定するのに役立ちます。

ヒープ プロファイル

ヒープ プロファイルの例
図 4.: ヒープ プロファイルの例。

ヒープ プロファイルにはネイティブ バージョンと Java バージョンの両方があり、メモリの問題のデバッグに最適です。コールスタック サンプルに似ていますが、CPU サイクルを測定するのではなく、メモリが割り当てられたときにサンプルを取得します。

ヒープ プロファイルを使用して、次のことを行うことをおすすめします。

  • メモリのチャーンを減らします。ヒープ プロファイルには、メモリ割り当てのコードの場所を含むサンプルが用意されています。これにより、一時オブジェクトを大量に作成する領域を特定できます。これは、アプリでガベージ コレクション(GC)が頻繁に発生する原因となる可能性があります。
  • メモリリークを検出する。ヒープ プロファイルは、他のメモリ プロファイルとともに使用して、メモリリークを診断して修正できます。これにより、想定よりも大幅に多くのメモリを割り当てている場所を特定できます。

プロファイルを結合する

多くの場合、パフォーマンスの分析には単一のプロファイルを使用します。ただし、複数のプロファイルや 1 つの結合プロファイルを収集すると、より完全な全体像を把握でき、単一のプロファイルだけでは診断できない複雑な問題の診断に役立つことがよくあります。

プロファイルを統合するとメリットがあるシナリオを次に示します。

  • シナリオ 1: 計測されていないコードを調査する。システム トレースには、すでに計測したオペレーションのレイテンシが表示されることがあります。ただし、その期間中に実行されたコードの計測されていない部分について、より詳細な情報が必要になる場合があります。調査するには、コールスタック プロファイルを取得して、実行されたコードを把握します。この情報を基に、トレース スライスを追加してトレースを改善できます。

  • シナリオ 2: メモリリークとガベージ コレクションの分析。システム トレースで、割り当てにより Java ヒープメモリが常に増加し、ガベージ コレクション(GC)が頻繁にトリガーされているとします。割り当てられたオブジェクトを理解するには、ヒープ プロファイルまたはヒープダンプを取得します。このアプローチを組み合わせることで、メモリ使用量を削減する方法を特定できます。たとえば、キャッシュを使用して無駄な割り当てや最適化可能な割り当てを減らすと、GC の発生を防ぐことができます。