Android アプリケーションで使用されているメモリをプログラムで確認するにはどうすればよいですか?
何か方法があればいいのですが。また、携帯電話の空きメモリもどうすれば取得できますか?
ベストアンサー1
Linux などの最新のオペレーティング システムでのメモリ使用量は、非常に複雑で理解しにくい領域であることに注意してください。実際、取得した数値を正しく解釈できる可能性は非常に低いです。(他のエンジニアとメモリ使用量の数値を確認するたびに、その実際の意味について長い議論が行われ、漠然とした結論しか得られません。)
注: より詳細なドキュメントができましたアプリのメモリを管理するここで紹介した内容の多くをカバーしており、Android の最新の状況も掲載されています。
まず最初に、この記事の最後の部分を読んでください。Android でメモリがどのように管理されるかについての説明があります。
次は、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
。
ここで注目すべき興味深い点は、Pss
とUss
は で見たものとわずかに (あるいはそれ以上に) 異なるということです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程度です。
Cached
RAM はファイルシステムのキャッシュなどに使用されます。一般的なシステムでは、ページング不良状態を回避するために、このために 20 MB 程度のメモリが必要です。Android のメモリ不足キラーは、特定のシステムに合わせて調整されており、キャッシュされた RAM がバックグラウンド プロセスによって消費されすぎてページングが発生する前に、バックグラウンド プロセスが強制終了されるようにします。