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 -l
145 個のスレッドまたはプロセスが実行されており、すべてが同じルート プロセス (Tomcat) にリンクされていることがわかります。
すべてを合計すると、(4096MB) + (1024MB) + (256MB) + 145 * (1024KB) = 5521MB の合計最大メモリが得られます。何がわかるjmap -heap PID
か、何がわかるかManagementFactory.memoryMXBean.(heapMemoryUsage + nonHeapMemoryUsage).getCommitted()
、そして上記の理論値はすべて対になっています。
Linux 側ではtop
、nmon
両方とも、このプロセスによって割り当てられた 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. これは、「セキュリティ マージン」にはほとんど多すぎます。
ですから、メモリがどこから使用されているのか、そしてなぜ制限に従わないのかを理解したいのです。情報が不足している場合は、喜んで提供します。