メモリ使用量(匿名 RSS + スワップ)は、アプリのメモリ使用量を反映する Android Vitals の指標です。
匿名メモリは、ストレージ上のファイルにバックアップされていないメモリです(ヒープ割り当てや mmap 割り当てメモリなど)。これにより、Java または Kotlin ヒープ、管理されていないネイティブ ヒープ割り当て(Android 8.0(API レベル 26)以降ではビットマップ ピクセルデータがここに格納されます)、スレッド実行スタックなど、アプリの動的メモリ割り当てがキャプチャされます。OS は負荷がかかるとファイル バックアップ メモリをドロップできますが、匿名メモリはドロップできません。
Resident Set Size(RSS)は、物理 RAM に保持されているプロセスで使用されるメモリページ(共有と非共有の両方)の合計数です。ページが複数のプロセス(同じライブラリにアクセスするアプリなど)によってアクセスされる場合、そのページは「共有」と見なされます。
匿名メモリの場合、メモリが不足すると、システムはページをスワップ領域(Android では zRAM)に書き込むことができます。システムは、必要に応じてこれらのページをスワップから読み取ることができます。
メモリ使用量(匿名 RSS + スワップ)は、ストレージ上のファイルにバックアップされていないアプリのメモリページの合計数を表します。これには、スワップでシステムによって保持されているメモリも含まれます。匿名 RSS とスワップをトラッキングすると、アプリの実際のメモリ使用量(削除不可)を確認できます。
アプリのメモリ使用量が多い場合は、このページのガイダンスに沿って問題をさらに調査し、解決してください。
高いメモリ使用量を特定する
Android Vitals
Android Vitals は、アプリのメモリ使用量を次のプロセス状態別に表示します。
- フォアグラウンド: アプリのプロセスが表示されます。P99 が高いと、ユーザーが認識するパフォーマンス(ジャンクや OOM クラッシュ)に影響することが多く、不要になった UI コンポーネントやアクティビティを保持することが主な原因です。
- 知覚可能サービス: アプリのプロセスが知覚可能な状態で実行されています。これには、フォアグラウンド サービス、優先ジョブ、ユーザーが開始するデータ転送ジョブが含まれます。システム バインド サービスや他のアプリによってバインドされたサービスにも拡張できます。これらのサービスは長時間実行タスク用に設計されているため、リークによるメモリの保持やリソースの解放の失敗により、P99 テールが時間の経過とともに増加する可能性があります。
- バックグラウンド: アプリがバックグラウンド サービスを実行しているか、最近バックグラウンドに移行したものの、まだキャッシュに保存されていない状態です。バックグラウンド処理のリークや解放されていないリソースが複合化されるのは、このときです。このプロセス状態はフォアグラウンド プロセスや知覚可能プロセスよりも重要度が低いため、この状態で大量のメモリを保持しないようにしてください。
- Cached: アプリがキャッシュに保存されている状態です。この状態は、LMK などのシステム メモリ プレッシャーに非常に敏感です。OS はこのプロセス状態を自由に削除できるため、この状態はデバッグ目的でのみ提供されます。
これらのプロセス状態と onTrimMemory コールバックの関連性については、イベントに応じてメモリを解放するのガイダンスをご覧ください。
Android Vitals では、アプリのメモリ使用量を RAM バケット別に分類することもできます。メモリ使用量の指標は、50 パーセンタイルと 90 パーセンタイルの最新の 1 日の値とともに、1 日のパーセンタイル値のタイムラインとして表示されます。
メモリのベースラインを特定したら、ガイダンスに沿ってメモリ使用量の過多を診断し、改善します。
テールスキューを使用してメモリリークを特定する
メモリリークを特定するには、Android Vitals で、一般的なユーザー(P50)と末端のユーザー(P90)の間に差異がないか確認します。一般的なアセットの肥大化は、すべてのパーセンタイルでメモリを均一に増加させますが、メモリリークは時間の経過とともに複合化し、テールエンドのデータを大きく歪めます。
P90 と P99 の指標を P50 ベースラインと比較する場合は、プロセス名で比較する必要があります。P90 と P50 の比率が 3.5 倍を超えている場合は、セッションの延長中にメモリリークが発生している可能性があります。特定のユースケースでは、比率の上昇が必ずしもリークを示すとは限りませんが、特定のワークフローを評価して、メモリ使用量の上昇が想定される動作かどうかを判断する必要があります。
リソース
メモリ使用量が多すぎる問題をローカルで診断する
メモリ使用量が過剰になる原因を診断するには、デベロッパー設定の [ヒープダンプを記録]、Android Studio、または Perfetto でヒープダンプをキャプチャします。アプリのコア ユーザー ジャーニーをテストした後、ローカルでヒープダンプをキャプチャすることから始めることをおすすめします。
特に、次のユーザー ジャーニーをテストすることをおすすめします。
- WebView とアプリ内ブラウザ セッション
- メディアを多用した無限スクロール
- アセットの作成と編集のフロー
メモリリークの可能性を調査するには、まず Android Vitals のメモリ使用量ダッシュボードの [プロセス名] テーブルを使用して、最もメモリを消費しているプロセスを特定します。次に、対応するユーザー ジャーニーをローカルで実行し、さまざまなプロセス状態(表示、フォアグラウンド サービス、キャッシュ)でヒープダンプを収集して、アプリがバックグラウンドに移行した後にメモリを解放するかどうかを確認します。
Android Studio Profiler を使用してメモリの問題をデバッグしている場合は、LeakCanary 統合を使用してリークと重複するビットマップの検出を効率化し、画像の使用を最適化することもできます。
ヒープダンプを収集したら、Perfetto AI Skills を使用してヒープダンプを分析し、メモリ使用量が多い原因を特定することをおすすめします。
AI スキルが応答する内容の例を次に示します。
I have completed the analysis of memory leaks and bitmap issues for [app] using the provided Perfetto trace.
Summary of Findings
The investigation identified a critical memory pressure issue caused by massive bitmap retention within the app process.
...
Recommendations for [app]
1. [Library] Image Cache Optimization:
* Review the [Library] caching strategy. Ensure that bitmaps
loaded for animations are released or downsampled when the animation is
not in the foreground.
2. Asset Resolution Audit:
* The 14.7 MB average size suggests full-screen or extremely high-density assets. Audit the [library] files in the native_home component to ensure they are not using unnecessarily large source images.
3. View Lifecycle Management:
* Investigate why 21 [LibraryImage] instances are alive simultaneously. Ensure that views in the bottom
tab are properly detached or their animations are cleared when switching between tabs.
4. Fix Surface Leaks:
* Address the Surface.release failures observed in the logs, as these can lead to both memory leaks and
native resource exhaustion.
ヒープダンプの解釈に関する追加リソース
ヒープダンプの解釈とメモリ使用量のデバッグの詳細については、次のリソースをご覧ください。
- 手動分析: Perfetto ヒープダンプ エクスプローラ ガイドを使用して、Perfetto UI でヒープダンプの可視化を操作して解釈する方法を学びます。
- Java/Kotlin の割り当て: Android ランタイム(ART)のヒープダンプを分析する手順については、最初の ART ヒープダンプを可視化するをご覧ください。
- ネイティブ割り当て: Perfetto ネイティブ プロファイリングのドキュメントで、ネイティブ(C/C++)メモリ プロファイルを収集して分析する方法を確認してください。
- CLI 検査: adb dumpsys meminfo を使用して、デバイス上のアプリのメモリ使用量の内訳をすばやく取得します。
- AI を活用した分析: Perfetto AI Skills を活用して LLM を活用した分析を実行し、トレース内のメモリリークと過剰な割り当てを検出します。
- SQL ベースの分析: Perfetto SQL とトレース分析スキルを使用して、構造化されたクエリと特殊なスクリプトを実行し、複雑なトレースデータを分析します。
メモリ使用量を改善する
アプリのメモリ使用量を改善する方法については、以下のセクションをご覧ください。
メモリの問題の修正に関する詳細なガイダンスについては、アプリのメモリを管理するガイドをご覧ください。