Android でアプリケーションのメモリ使用量を確認するにはどうすればいいですか? 質問する

Android でアプリケーションのメモリ使用量を確認するにはどうすればいいですか? 質問する

Android アプリケーションで使用されているメモリをプログラムで確認するにはどうすればよいですか?

何か方法があればいいのですが。また、携帯電話の空きメモリもどうすれば取得できますか?

ベストアンサー1

Linux などの最新のオペレーティング システムでのメモリ使用量は、非常に複雑で理解しにくい領域であることに注意してください。実際、取得した数値を正しく解釈できる可能性は非常に低いです。(他のエンジニアとメモリ使用量の数値を確認するたびに、その実際の意味について長い議論が行われ、漠然とした結論しか得られません。)

注: より詳細なドキュメントができましたアプリのメモリを管理するここで紹介した内容の多くをカバーしており、Android の最新の状況も掲載されています。

まず最初に、この記事の最後の部分を読んでください。Android でメモリがどのように管理されるかについての説明があります。

Android 2.0 以降のサービス API の変更

次は、ActivityManager.getMemoryInfo()全体的なメモリ使用量を確認するための最高レベルの API です。これは主に、バックグラウンド プロセス用のメモリがシステムにどれだけ近づいているかをアプリケーションが判断し、サービスなどの必要なプロセスを強制終了する必要があるかを判断するのに役立ちます。純粋な Java アプリケーションの場合、Java ヒープ制限は、1 つのアプリケーションがシステムにこの時点まで負荷をかけないようにするためのものであるため、これはあまり役に立ちません。

より低レベルになると、デバッグ API を使用して、メモリ使用量に関する生のカーネルレベルの情報を取得できます。android.os.デバッグ.メモリ情報

ActivityManager.getProcessMemoryInfo注: 2.0 以降では、別のプロセスに関するこの情報を取得するためのAPI もあります。アクティビティマネージャ.getProcessMemoryInfo(int[])

これは、次のすべてのデータを含む低レベルの MemoryInfo 構造を返します。

    /** The proportional set size for dalvik. */
    public int dalvikPss;
    /** The private dirty pages used by dalvik. */
    public int dalvikPrivateDirty;
    /** The shared dirty pages used by dalvik. */
    public int dalvikSharedDirty;

    /** The proportional set size for the native heap. */
    public int nativePss;
    /** The private dirty pages used by the native heap. */
    public int nativePrivateDirty;
    /** The shared dirty pages used by the native heap. */
    public int nativeSharedDirty;

    /** The proportional set size for everything else. */
    public int otherPss;
    /** The private dirty pages used by everything else. */
    public int otherPrivateDirty;
    /** The shared dirty pages used by everything else. */
    public int otherSharedDirty;

Pssしかし、、、PrivateDirtyおよび...の違いは何かというと、SharedDirtyここからが面白いところです。

Android (および Linux システム全般) のメモリの多くは、実際には複数のプロセス間で共有されています。そのため、プロセスが使用するメモリの量は実際には不明です。さらに、ディスクへのページ アウト (Android では使用しないスワップは言うまでもありません) を追加すると、さらに不明瞭になります。

したがって、各プロセスに実際にマップされているすべての物理 RAM を取得し、すべてのプロセスを合計すると、実際の合計 RAM よりもはるかに大きな数値になる可能性があります。

このPss数値は、メモリ共有を考慮してカーネルが計算するメトリックです。基本的に、プロセス内の RAM の各ページは、そのページを使用している他のプロセスの数の比率でスケーリングされます。この方法では (理論上は) すべてのプロセスの pss を合計して、プロセスが使用している RAM の合計を確認し、プロセス間の pss を比較して、プロセスの相対的な重みを大まかに把握できます。

ここでのもう 1 つの興味深いメトリックはPrivateDirty、基本的にプロセス内の RAM の量であり、ディスクにページングできず (ディスク上の同じデータによってバックアップされていない)、他のプロセスと共有されません。これを別の方法で見るには、そのプロセスがなくなったときにシステムで使用できるようになる RAM を調べます (おそらくすぐにキャッシュやその他の用途に取り込まれます)。

これがこのための SDK API のほぼすべてです。ただし、開発者としてデバイスで実行できる操作は他にもたくさんあります。

を使用するとadb、実行中のシステムのメモリ使用量に関する多くの情報を取得できます。一般的なものとしては、adb shell dumpsys meminfo各 Java プロセスのメモリ使用量に関する大量の情報を吐き出す コマンドがあります。これには上記の情報のほか、さまざまな情報が含まれます。また、単一のプロセスの名前または pid を追加して確認することもできます。たとえば、adb shell dumpsys meminfo systemシステム プロセスを表示します。

** pid 890 [システム] の MEMINFO **
                    ネイティブダルビックその他合計
            サイズ: 10940 7047 該当なし 17987
       割り当て: 8943 5516 N/A 14459
            無料: 336 1531 N/A 1867
           (PSS):4585 9282 11916 25783
  (共有ダーティ): 2184 3596 916 6696
    (プライベートダーティ): 4504 5956 7456 17916

 オブジェクト
           閲覧数: 149 閲覧ルート: 4
     AppContexts: 13 アクティビティ: 0
          資産: 4 資産管理者: 4
   ローカルバインダー: 141 プロキシバインダー: 158
死亡受取人: 49
 OpenSSL ソケット: 0

 構文
            ヒープ: 205 dbFiles: 0
       ページ数: 0 非アクティブページ KB: 0
    アクティブページKB: 0

上部のセクションがメインのセクションで、 はsize特定のヒープのアドレス空間の合計サイズ、allocatedはヒープが持っていると想定している実際の割り当ての KB、freeはヒープが追加割り当て用に持っている残りの空き KB、pssおよび はpriv dirty前に説明したものと同じで、各ヒープに関連付けられたページに固有です。

すべてのプロセスにわたるメモリ使用量を確認したい場合は、 コマンドを使用できますadb shell procrank。同じシステムでのこのコマンドの出力は次のようになります。

  PID Vss Rss Pss Uss コマンドライン
  890 84456K 48668K 25850K 21284K システムサーバー
 1231 50748K 39088K 17587K 13792K com.android.launcher2
  947 34488K 28528K 10834K 9308K com.android.wallpaper
  987 26964K 26956K 8751K 7308K com.google.process.gapps
  954 24300K 24296K 6249K 4824K com.android.phone
  948 23020K 23016K 5864K 4748K com.android.inputmethod.latin
  888 25728K 25724K 5774K 3668K 受精卵
  977 24100K 24096K 5667K 4340K android.process.acore
...
   59 336K 332K 99K 92K /システム/bin/installd
   60 396K 392K 93K 84K /システム/bin/キーストア
   51 280K 276K 74K 68K /システム/bin/サービスマネージャー
   54 256K 252K 69K 64K /system/bin/デバッガー

ここでVss、 およびRss列は基本的にノイズです (これらはプロセスの単純なアドレス空間と RAM 使用量であり、プロセス全体の RAM 使用量を合計すると途方もなく大きな数値になります)。

Pssは前に見た通りであり、UssですPriv Dirty

ここで注目すべき興味深い点は、PssUssは で見たものとわずかに (あるいはそれ以上に) 異なるということですmeminfo。なぜでしょうか。 procrank は とは異なるカーネル メカニズムを使用してデータを収集しておりmeminfo、わずかに異なる結果を返します。なぜでしょうか。 正直に言って、私には見当もつきません。 の方が正確かもしれないと思いますprocrankが、実際には、これは「取得したメモリ情報は鵜呑みにしないでください。多くの場合、非常に大きな鵜呑みにしないでください」という点だけを残しています。

最後に、システムの全体的なメモリ使用量の概要を示すコマンドがありますadb shell cat /proc/meminfo。ここには大量のデータがありますが、議論する価値があるのは最初の数個の数字だけです (残りの数字は理解できる人がほとんどおらず、私がそれらの人に質問すると、矛盾した説明が返ってくることがよくあります)。

メモリ合計: 395144 kB
メモリ空き容量: 184936 kB
バッファ: 880 kB
キャッシュ: 84104 kB
スワップキャッシュ: 0 kB

MemTotalカーネルとユーザー空間で使用可能なメモリの合計量です (RAM の一部は無線、DMA バッファなどに必要なため、デバイスの実際の物理 RAM よりも少なくなることがよくあります)。

MemFreeまったく使用されていないRAMの量です。ここで表示される数値は非常に高いですが、Androidシステムでは通常、利用可能なメモリを使用してプロセスを実行し続けるため、これは数MB程度です。

CachedRAM はファイルシステムのキャッシュなどに使用されます。一般的なシステムでは、ページング不良状態を回避するために、このために 20 MB 程度のメモリが必要です。Android のメモリ不足キラーは、特定のシステムに合わせて調整されており、キャッシュされた RAM がバックグラウンド プロセスによって消費されすぎてページングが発生する前に、バックグラウンド プロセスが強制終了されるようにします。

おすすめ記事