9

Java プロセスが実際にどれだけのメモリを使用しているかを調べるために、利用可能なほとんどの方法を調査しました。これまでのところ、割り当てられたメモリの合計は、次の 1 つ以上になる可能性があることがわかっています。

  • ヒープメモリ (おそらく私の -XX:MaxHeapSize=4096m によって制御されます)
  • 永久メモリ (おそらく私の -XX:MaxPermSize=1024m によって制御されます)
  • 予約済みコード キャッシュ (おそらく -XX:ReservedCodeCacheSize=256m によって制御されます)
  • N of Threads * Thread Size (おそらく私の -XX:ThreadStackSize=1024 によって制御されます)

しかし、結果はLinuxが私に教えてくれるものとは大きく異なります.Javaプロセスのメモリ消費量を取得するために私が見つけた方法のいずれかです。

私の場合、Ubuntu 11.10 x86_64 マシン、JVM 1.6_u26 64 ビットで実行されている Tomcat インスタンスであり、ps -ALcf | grep org.apache.catalina.startup.Bootstrap | wc -l145 個のスレッドまたはプロセスが実行されており、すべてが同じルート プロセス (Tomcat) にリンクされていることがわかります。

すべてを合計すると、(4096MB) + (1024MB) + (256MB) + 145 * (1024KB) = 5521MB の合計最大メモリが得られます。何がわかるjmap -heap PIDか、何がわかるかManagementFactory.memoryMXBean.(heapMemoryUsage + nonHeapMemoryUsage).getCommitted()、そして上記の理論値はすべて対になっています。

Linux 側ではtopnmon両方とも、このプロセスによって割り当てられた ResidentMemory は 5.8GB -> 約 5939,2MB であることがわかりました。しかし、これはメモリの一部、ライブ RAM メモリの一部にすぎないこともわかっています。VIRT bytopと Size by nmon(どちらも同じことを表すはずです) は、プロセスが 7530MB (正確には 7710952KB by nmon) であることを示しています。これは、予想される最大値とは大きく異なります: 最大値を2009MB 上回っており、jmap と jstat によると、ヒープ メモリの割り当てはピークに達していません (2048-OldSpace + 1534-Eden_+_Survivors)。

topまた、コード スタックが 36KB (最初のカタリナ スターターの場合は公平)、データ スタックが 7.3GB (残りを表す) であることもわかります。

この tomcat サーバー インスタンスは、このマシンで実行されている唯一のインスタンスであり、不安定な状態が続いています。マシンには 7647544k の RAM があり、(パフォーマンス上の理由から) スワップがないため、3 日ごとに再起動する必要があります。私は制限の計算を行い、プロセスがそれらに従うことを期待して、マシン上で実行されている他のすべてのサービスのために残しておくのはかなり良いセキュリティマージンであることがわかりました(sshとtop自体以外に問題はありません):7468 - 5521 = 1947. これは、「セキュリティ マージン」にはほとんど多すぎます。

ですから、メモリがどこから使用されているのか、そしてなぜ制限に従わないのかを理解したいのです。情報が不足している場合は、喜んで提供します。

4

2 に答える 2

5

-Xmsプレーンでシンプルな JVM は、および-Xmxおよびその他のコマンド ライン パラメータで提供されるメモリよりも多くのメモリを使用します。

これは、JVMがメモリを割り当てて管理する方法に関する非常に詳細な記事です。質問の仮定に基づいて期待されるほど単純ではありません。包括的に読む価値があります。

多くの実装での ThreadStack サイズには、オペレーティング システムや場合によっては JVM のバージョンによって異なる最小制限があります。JVM または OS のネイティブ OS 制限よりも低い制限を設定すると、スレッドスタック設定は無視されます (代わりに *nix の ulimit を設定する必要がある場合があります)。他のコマンド ライン オプションも同じように機能し、指定された値が小さすぎると、黙ってより高い値にデフォルト設定されます。渡されたすべての値が実際に使用されているものを表していると想定しないでください。

クラスローダー、およびTomcatには複数あり、簡単に文書化されていない多くのメモリを消費します。JIT は大量のメモリを消費し、時間とスペースを交換します。これは、ほとんどの場合、適切なトレードオフです。

あなたが引用する数字は、私が予想するものにかなり近いです。

于 2012-05-30T15:11:07.860 に答える
3

仮想メモリは、使用されるアドレス空間の量です。これは、64 ビット アプリケーションを使用しているため、あまり気にする必要はありません。レジデントは、実際に使用されるメイン メモリの量です。

リストに追加できます

  • JVM を含む共有ライブラリ。~0.5G
  • 直接メモリー (0 から 4G) 最大値はデフォルトでヒープの最大値と同じです。
  • メモリ マップ ファイル。制限なし。

を実行して、pmapどのような目的でどのくらいのアドレス空間が使用されているかを表示できます。

ところで: メモリ マップ ファイルが原因で、上部に 640G VIRT を表示しているプロセスがあります。居住者のサイズよりもはるかに大きくなる可能性があります。;)

于 2012-05-30T15:13:30.610 に答える