Android のメモリの理解とトラブルシューティング

メモリは、Android 搭載デバイスにおいて重要かつ有限なリソースです。Android プラットフォーム デベロッパーまたは OEM にとって、Java ランタイムから Linux カーネルに至るまで、あらゆるレベルでメモリがどのように機能するかを理解することは、パフォーマンスが高く安定したシステムを構築するために不可欠です。

このガイドでは、Android のメモリアーキテクチャ、分析に使用できるツール、メモリ関連の問題を特定して解決するための実践的な演習について、包括的な概要を説明します。

目標

このガイドを完了すると、次のことができるようになります。

  • Zygote プロセスモデルやメモリマップド ファイルなど、Android メモリの基本コンセプトを説明する。
  • Resident Set Size(RSS)、Proportional Set Size(PSS)、Unique Set Size(USS)の違いを説明する。
  • dumpsys meminfo や showmap などの標準的なコマンドライン ツールを使用して、メモリ使用量をすばやく評価します。
  • AHAT を使用して Java ヒープダンプをキャプチャして分析し、リークと過剰な割り当てを検出します。
  • Perfetto と heapprofd を使用して、システム全体で Java メモリとネイティブ メモリの両方をプロファイリングします。
  • Pressure Stall Information(PSI)などのシステム全体のメモリ プレッシャー インジケーターを理解し、Low Memory Killer(LMK)のアクティビティをモニタリングします。
  • ZRAM スワップやページ キャッシュの強制排除など、カーネルレベルの回収アクティビティを監視します。

ガイドの構成

このガイドは、次のセクションで構成されており、順番に読むように設計されています。

  1. 基本コンセプト: Android メモリのコア技術原則。
  2. 迅速な評価ツール: meminfo、showmap、procstats を使用して迅速なトリアージを行います。
  3. Java メモリの分析: AHAT を使用して Java ヒープを特集します。
  4. ビットマップとメモリ: 画像が RAM に与える影響を理解し、ツールを使用して画像をプロファイリングします。
  5. ネイティブ メモリの分析: Perfetto と heapprofd を使用した C/C++ メモリのプロファイリング。
  6. WebView とメモリ: WebView のマルチプロセス アーキテクチャとメモリ使用量について説明します。
  7. アプリコードはメモリ: クラスの読み込みと dex の肥大化が RAM に与える影響について説明します。
  8. スレッドとメモリ: ネイティブ スレッド スタックのコストを分析します。
  9. メモリの局所性とパフォーマンス: データアクセス パターンが CPU パフォーマンスにどのように影響するかを理解します。
  10. サービス バインディングとプロセス状態: プロセス間の依存関係が OOM スコアにどのように影響するかを理解します。
  11. システム全体のトラブルシューティング: PSI、LMK、ZRAM スワップ、ページ キャッシュの強制排除をモニタリングします。
  12. メモリの再利用: エビクションとスワップ: memory.reclaim を使用した memcg、チャージ、プロアクティブな再利用について説明します。
  13. kswapd と lmkd の相互作用: 負荷がかかった状態で kswapd と lmkd がどのように連携するかを理解します。
  14. メモリページを OS に返す: madvise と posix_fadvise を使用して、未使用のヒープページとファイル キャッシュ ページをカーネルに返します。
  15. 無駄のないプロセスでバックグラウンド処理を維持する: バックグラウンド サービスとワーカーを専用のプロセスに移動して、UI とグラフィック メモリが高い優先度で保持されないようにします。

前提条件と環境

このガイドでは、Android のメモリの問題を診断して解決する方法を示すリファレンス ワークフロー、ベンチマーク データ、ケーススタディを紹介します。

  • 分析ツール: このガイドの手法では、主に標準の Android パフォーマンス ツール(Perfetto、dumpsys meminfo、showmap、AHAT など)を使用します。
  • root 権限: 一部のシステムレベルの診断ワークフロー(カーネルメモリの負荷やハードウェア PMU カウンタの検査など)では、userdebug デバイスまたはエミュレータ ビルドで昇格された root 権限(adb root)が必要です。

ここから開始: 基本コンセプト