4

Linuxでプロセス(Javaプログラム)のメモリ使用量を測定しようとしていますが、それに関連する2つの質問があります。

  1. スクリプトps_mem.py(/ proc / $ PID / smapsの値を合計)を使用してみましたが、合計メモリ使用量のピークは約135MB(プライベートメモリと共有メモリ)でした。共有メモリの容量は1MB未満です。MassifツールでValgrindを使用しようとすると、valgrind --tool=massif --trace-children=yes --stacks=yes java myProgramメモリ使用量のピーク時に約10MBが生成されます。
    私が理解しているように、ヒープは私のプログラムの変数が格納される場所ですが、2つのメソッドの違いは、コード自体(jvmを含む)が占めるスペースであることを意味しますか?

  2. 同じプログラムが異なる量のRAMを持っている場合、または/および異なるプロセッサ(ARMまたはx86)を使用している場合、異なるマシンで異なる量のメモリを使用しますか?

4

4 に答える 4

3
  1. 依存します。
    • の共有メモリマッピングの多くは、smapsディスク上のライブラリ/バイナリによって直接サポートされています。これらのフットプリントは重要ですが、システムはいつでもこれらのページをドロップし、必要に応じてディスクからリロードできるため、それほど重要ではありません。
    • ダーティまたはプライベートなものはすべて、現在のプロセスにのみ属します(プログラムが実行者なしでフォークする場合は、プロセスツリー)。これらのページをメモリからプッシュする必要がある場合、システムはスワップのためにそれらを保存する必要があるため、これはより重要です。
    • 山塊が測定しているものは、おそらく後者と相関しています。ただし、JVM自体(プログラムなし)が使用するメモリは両方にあります。
  2. はい。JavaまたはJavaが使用するライブラリは、使用可能なRAMのサイズに応じてメモリモデルを調整する場合があります。異なるアーキテクチャでは、完全に異なるバイナリを使用しています。バイナリは、大きくなったり小さくなったり、配置が異なったり、JITとメモリ管理に異なる戦略を使用したりする場合があります。
于 2009-12-11T18:54:37.887 に答える
3

これ以外にも同様の質問があり、ここで同じ質問に答えて、Linux proc statvminfoが現在どのように正確でないかを人々に知らせます。
Valgrindは詳細情報を表示できますが、ターゲットアプリケーションの速度が大幅に低下し、ほとんどの場合、アプリの動作が変わります。

WRTの「メモリ使用量」について誰もが知りたいのは次のことだと思います...
Linuxでは、1つのプロセスが使用する可能性のある物理メモリの量は大きく次のカテゴリに分類できます。

  • Ma匿名マップトメモリ
    • .pプライベート
      • .d汚れ==malloc/マップされたヒープとスタックに割り当てられて書き込まれたメモリ
      • .c clean == malloc / mmappedヒープおよびスタックメモリが割り当てられ、書き込まれ、解放されますが、まだ再利用されていません
    • .s共有
      • .d汚れ==何もないはずです
      • .cclean==存在しないはずです
  • マップトメモリという名前のMn
    • .pプライベート
      • .d汚れ==ファイルmmapされた書き込みメモリプライベート
      • .cclean==マップされたプログラム/ライブラリテキストプライベートマップ
    • .s共有
      • .d汚れ==ファイルのmmapされた書き込みメモリ共有
      • .cclean==マップされたライブラリテキスト共有マップされた

オーバーヘッドを最小限に抑えて実数を取得するには、次のように数値を取得することをお勧めします。
psがRSSとして表示するものを分割し、混乱しないように、より正確な数値を取得するには、これらを合計する必要があります。
/ proc /(pid)/ statusはこれらの番号を表示しようとしますが、失敗します。
したがって、[anon]、[stack]に各マッピングに正しくラベルを付ける代わりに、Linuxカーネルの人々がprocエントリコードをメインライン化して、これらのMapd、Mapc、Mnpd、....の数値を合計して表示することを望みます。
組み込みLinuxの人々は本当に幸せな私見を得るでしょう。

マップ:

 awk '/^[0-9a-f]/{if ($6=="") {anon=1}else{anon=0}} /Private_Dirty/{if(anon) {asum+=$2}else{nasum+=$2}} END{printf "sum=%d\n",asum}' /proc/<pid>/smaps

Mapc:

 awk '/^[0-9a-f]/{if ($6=="") {anon=1}else{anon=0}} /Private_Clean/{if(anon) {asum+=$2}else{nasum+=$2}} END{printf "sum=%d\n",asum}' /proc/<pid>/smaps

Mnpd:...など

于 2010-01-04T14:46:20.890 に答える
1

#1の場合、共有メモリは、複数のプロセスによって(潜在的に)使用されるメモリです。これは基本的に、同じバイナリファイルを複数のプロセスで実行する場合、または異なるプロセスが共有ライブラリを使用している場合です。newヒープは、割り当てられたメモリが格納される場所です( Javaで使用する場合)。JavaにはVMがあるため、Javaコードには表示されないプロセスレベルで大量のメモリが割り当てられます。はい、その135MBの大部分はJVMコード/データ自体からのものだと思います。ただし、スタックによって占有されるメモリもあります(関数呼び出しを行ってローカル変数を使用する場合)。

#2の場合、RAMの量が異なっても、メモリをRAM+スワップスペースと等しくした場合に使用される「メモリ」の量には影響しません。ただし、プロセッサが異なれば(特に、32ビットと64ビットについて話している場合)、使用するメモリの量が異なる場合があります。また、プロセスのコンパイル方法によって、使用されるメモリの量が変わる可能性があります。これは、速度よりもメモリフットプリントを最適化するようにコンパイラに指示したり、一部またはすべての最適化を完全に無効にしたりできるためです。

于 2009-12-11T18:46:24.507 に答える
0

JConsoleをご覧になることをお勧めします。測定の目的によっては、注意が必要な場合があります。Javaプログラムのメモリ使用量を知りたい場合、プロセスのメモリ使用量を測定するツールは、JVMとプログラムによって使用されるメモリを表示するため、不正確になります。

massifツールに関しては、JVMの一部がスタックに格納され、Javaコード自体がヒープ上にある可能性があることを知っておく必要があります(JVMの変数であるため)。いう。

于 2009-12-11T18:47:00.980 に答える