[解決済み] Androidでアプリケーションのメモリ使用量を確認するにはどうすればよいですか?
質問
Androidアプリケーションのメモリ使用量をプログラムで確認するにはどうしたらいいですか?
何か方法があればいいのですが。さらに、携帯電話の空きメモリも取得するにはどうすればいいのでしょうか?
解決方法は?
Linuxのような最新のOSでは、メモリ使用量は 極めて 複雑で理解しにくい分野です。 実際、どのような数字であっても、実際に正しく解釈できる可能性は極めて低いのです。 (私が他のエンジニアとメモリ使用量の数字を見るたびに、いつもその数字の意味について長い議論が交わされ、曖昧な結論にしかならない)。
注:現在、私たちは、より充実したドキュメントで アプリのメモリ管理 は、ここに書かれている内容の多くをカバーし、Androidの状態についてより最新である。
まず最初に、この記事の最後の部分を読んでください。Androidでメモリがどのように管理されているかについての議論があります。
現在
ActivityManager.getMemoryInfo()
は、全体的なメモリ使用量を見るための最高レベルのAPIです。 これは主に、システムがバックグラウンド・プロセス用のメモリを失い、サービスのような必要なプロセスを殺す必要が出てくるまでの時間を、アプリケーションが測定するのに役立つものです。 なぜなら、Javaのヒープ制限は、1つのアプリケーションがこの時点までシステムにストレスを与えることを避けるために存在する部分があるからです。
より低いレベルでは、Debug API を使用して、メモリ使用量に関する生のカーネルレベルの情報を取得することができます。 android.os.Debug.MemoryInfo
2.0 からは、API もあります。
ActivityManager.getProcessMemoryInfo
を使用すると、別のプロセスに関するこの情報を取得することができます。
ActivityManager.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システム全般)では、多くのメモリが実際には複数のプロセスで共有されています。 そのため、1つのプロセスがどれだけのメモリを使用しているかは、実際には明らかではありません。 さらに、ディスクへのページングアウト(Androidでは使っていないスワップは別として)を加えると、さらにわからなくなります。
したがって、各プロセスに実際にマッピングされている物理 RAM をすべて取り出して、すべてのプロセスを合計すると、おそらく実際の総 RAM よりもはるかに大きな数字になるはずです。
その
Pss
基本的に、あるプロセスの RAM の各ページは、そのページを使用している他のプロセスの数の比率でスケーリングされます。 このようにして、(理論的には) すべてのプロセスの pss を合計して、それらのプロセスが使用している総 RAM を確認したり、プロセス間の pss を比較して、それらの相対的な重みを大まかに把握したりすることができるのです。
ここでもう1つ興味深い指標は
PrivateDirty
これは基本的に、ディスクにページングできず(ディスク上の同じデータによってバックアップされていない)、他のプロセスと共有されていない、プロセス内部のRAMの量です。 別の見方をすれば、そのプロセスがなくなったときにシステムで利用可能になるRAMです(おそらくすぐにキャッシュや他の用途に吸収されるでしょう)。
これがSDKのAPIのほぼ全てです。 しかし、開発者としてあなたのデバイスでできることはもっとあります。
使用方法
adb
を使えば、実行中のシステムのメモリ使用量について多くの情報を得ることができます。 一般的なものは、コマンド
adb shell dumpsys meminfo
これは、各Javaプロセスのメモリ使用量について、上記の情報と他の様々なものを含む多くの情報を吐き出すものです。 また、1つのプロセスの名前かpidを付けて、例えば次のように見ることもできます。
adb shell dumpsys meminfo system
システムプロセスを教えてください。
** pid 890 [system]のMEMINFO **。 ネイティブ ダルビック その他 合計 サイズ: 10940 7047 N/A 17987 が割り当てられています。 8943 5516 無し 14459 フリー 336 1531 未満 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 SQL ヒープ: 205 dbFiles: 0 numPagers: 0 inactivePageKB: 0 アクティブページKB: 0
上段がメインで、ここで
size
は、特定のヒープのアドレス空間における総サイズです。
allocated
は、そのヒープが持っていると考えている実際のアロケーションのkbです。
free
は、ヒープが追加で割り当てることができる残りのKBで
pss
と
priv dirty
は、それぞれのヒープに関連するページについて、前に説明したのと同じです。
全プロセスのメモリ使用量を見るだけなら、コマンド
adb shell procrank
. 同じシステムでこれを出力すると、次のようになります。
PID Vss Rss Pss Uss cmdline 890 84456K 48668K 25850K 21284K system_server 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 zygote 977 24100K 24096K 5667K 4340K android.process.acore ... 59 336K 332K 99K 92K /system/bin/installd 60 396K 392K 93K 84K /system/bin/keystore 51 280K 276K 74K 68K /system/bin/servicemanager 54 256K 252K 69K 64K /system/bin/debuggerd
ここで
Vss
と
Rss
列は基本的にノイズです (これらはプロセスのアドレス空間と RAM 使用量です。プロセス全体の RAM 使用量を合計すると、とんでもなく大きな数字になります)。
Pss
は以前から見てきたとおりで
Uss
は
Priv Dirty
.
ここで興味深いことがあります。
Pss
と
Uss
で見たものとは若干(いや、それ以上)異なっています。
meminfo
. なぜでしょうか? procrankはデータを収集するのに違うカーネル・メカニズムを使います。
meminfo
となり、微妙に異なる結果が得られます。 それはなぜか? 正直なところ、私にはわかりません。 私は
procrank
しかし、これはあくまで「塩の粒のような、しばしば非常に大きな粒のような記憶情報を入手すること」である。
最後にコマンドを紹介します。
adb shell cat /proc/meminfo
これは、システム全体のメモリ使用量の概要を示すものです。 ここにはたくさんのデータがありますが、議論に値するのは最初の数個だけです (そして残りの数値はほとんど理解されておらず、私がその数人に質問すると、しばしば矛盾した説明になってしまいます)。
メモリ総量:395144kB メモリフリー:184936キロバイト バッファ 880キロバイト キャッシュ:84104kB SwapCached: 0 kB
MemTotal
は、カーネルとユーザースペースが利用できるメモリの合計量です(RAMの一部は無線やDMAバッファなどに必要なため、デバイスの実際の物理RAMより少ないことがよくあります)。
MemFree
は、全く使用されていないRAMの量です。 Androidシステムでは、プロセスを実行し続けるために使用可能なメモリを使用しようとするため、通常、これは数MBにしかなりません。
Cached
は、ファイルシステムのキャッシュなどに使用されるRAMです。 Android のメモリ不足解消ツールは、キャッシュされた RAM が消費されすぎてページングが発生する前にバックグラウンドプロセスを終了させるよう、特定のシステム向けに調整されています。
関連
-
xxx:jarのアーティファクトディスクリプタの読み込みに失敗した問題は解決しました。
-
mavenプロジェクトのテストエラー java.lang.ClassNotFoundException: org.glassfish.jersey.client.ClientConfig の問題を解決する。
-
IDEA パッケージステートメントの欠落
-
[解決済み] Androidのソフトキーボードをプログラムで閉じる/隠すにはどうすればよいですか?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] java.net.URLConnectionを使用してHTTPリクエストを発生させ処理する方法
-
[解決済み] アプリケーションを終了することは嫌われますか?
-
[解決済み] Androidで現在の時刻と日付を取得する方法
-
[解決済み] Javaで、オブジェクトの大きさを決定する最も良い方法は何ですか?
-
[解決済み】Android UserManager.isUserAGoat()の正しい使用例?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
java.util.NoSuchElementException 原因解析と解決方法
-
javaで非静的な解を静的な参照にすることができない
-
JQuery DataTable 详解
-
Methodのinvokeメソッド実装のJavaリフレクション
-
spring aop アドバイスからの Null 戻り値が、サマリーのプリミティブ戻り値と一致しない。
-
IDEA パッケージステートメントの欠落
-
ローカルリソースのロードが許可されていない場合の解決策
-
コミットには何も追加されないが、未追跡のファイルが存在し、gitで未追跡のファイルに対する完璧な解決策
-
[解決済み] アプリが使用できるRAMの最大量はどのくらいですか?
-
[解決済み] Androidのアプリケーションヒープサイズを検出する