制御したいものを制御することはできません-Xmx
.Javaヒープのみを制御し、JVMによるネイティブメモリの消費を制御しません.JVMは実装に基づいて完全に異なる方法で消費されます. VisualVM は、ヒープが消費しているものを表示するだけで、JVM 全体がOS プロセスとしてネイティブ メモリとして消費しているものを表示しません。それを確認するには、OS レベルのツールを使用する必要があります。JVM はまったく異なる方法でネイティブ メモリを使用するため、それらは根本的に異なる数値を報告します。通常、VisualVM が報告するものよりもはるかに大きくなります。
次の記事Thanks for the Memory (Understanding How the JVM uses Native Memory on Windows and Linux) から
ヒープとガベージ コレクターを維持すると、制御できないネイティブ メモリが使用されます。
Java ヒープを維持するメモリ管理システムの状態を維持するには、より多くのネイティブ メモリが必要です。空きストレージを追跡し、ガベージ コレクションの進行状況を記録するには、データ構造を割り当てる必要があります。これらのデータ構造の正確なサイズと性質は実装によって異なりますが、多くはヒープのサイズに比例します。
JIT コンパイラはネイティブ メモリを使用しますjavac
。
バイトコード コンパイルはネイティブ メモリを使用しますが (gcc などの静的コンパイラの実行にメモリが必要なのと同じように)、JIT からの入力 (バイトコード) と出力 (実行可能コード) の両方もネイティブ メモリに格納する必要があります。多くの JIT コンパイル メソッドを含む Java アプリケーションは、小さなアプリケーションよりも多くのネイティブ メモリを使用します。
そして、ネイティブメモリを使用するクラスローダーがあります
Java アプリケーションは、オブジェクト構造とメソッド ロジックを定義するクラスで構成されます。また、Java ランタイム クラス ライブラリ (java.lang.String など) のクラスを使用し、サード パーティのライブラリを使用する場合もあります。これらのクラスは、使用されている限りメモリに格納する必要があります。クラスの格納方法は、実装によって異なります。
スレッドのセクションを引用することさえし
-Xmx
ません。あなたは、それが制御すると考えているものを制御せず、JVM ヒープを制御し、すべてが JVM ヒープに入るわけではなく、ヒープがさらに多くを占有するという考えを理解していると思います。管理と簿記のために指定したネイティブメモリ。
-Xms
プレーンでシンプルな JVM は、および-Xmx
およびその他のコマンド ライン パラメータで提供されるメモリよりも多くのメモリを使用します。
これは、JVMがメモリを割り当てて管理する方法に関する非常に詳細な記事です。質問の仮定に基づいて期待されるほど単純ではありません。包括的に読む価値があります。
多くの実装での ThreadStack サイズには、オペレーティング システムや場合によっては JVM のバージョンによって異なる最小制限があります。JVM または OS のネイティブ OS 制限よりも低い制限を設定すると、スレッドスタック設定は無視されます (代わりに *nix の ulimit を設定する必要がある場合があります)。他のコマンド ライン オプションも同じように機能し、指定された値が小さすぎると、黙ってより高い値にデフォルト設定されます。渡されたすべての値が実際に使用されているものを表していると想定しないでください。
クラスローダー、およびTomcatには複数あり、簡単に文書化されていない多くのメモリを消費します。JIT は大量のメモリを消費し、時間とスペースを交換します。これは、ほとんどの場合、適切なトレードオフです。