web-dev-qa-db-ja.com

JVMスタック、ヒープ、およびスレッドを物理メモリまたはオペレーティングシステムにマップする方法

コンパイラブック(ドラゴンブック)は、値型がスタック上に作成され、参照型がヒープ上に作成されることを説明しています。

Javaの場合、JVMにはランタイムデータ領域にヒープとスタックも含まれます。オブジェクトと配列はヒープ上に作成され、メソッドフレームはスタックにプッシュされます。 1つのヒープはすべてのスレッドで共有されますが、各スレッドには独自のスタックがあります。次の図にこれを示します。

enter image description here

Javaランタイムデータ領域 の詳細。

私が理解していないのは、JVMは本質的にソフトウェアであるため、これらのJVMヒープ、スタック、スレッドは物理マシンにどのようにマッピングされるのかということです。

だれかがJavaとC++の間でこれらの概念を比較できる場合、感謝します。JavaはJVM上で実行されますが、C++はそうではありません。

この質問をより正確にするために、次のことを知りたいと思います。

  1. Javaと比較すると、C++ランタイムデータ領域はどのように見えますか?写真は参考になりますが、上記のJVMのような良い写真は見つかりません。
  2. JVMのヒープ、スタック、レジスタ、スレッドはどのようにオペレーティングシステムにマッピングされますか?または私はそれらが物理マシンにどのようにマッピングされるのか尋ねるべきですか?
  3. 各JVMスレッドは単なるユーザースレッドであり、何らかの方法でkernalにマップされるのは本当ですか? (ユーザースレッドとカーネルスレッド)

Update:プロセスのランタイム物理メモリの図を描画します。
enter image description here

51
Ryan

私が理解していないのは、JVMは本質的にソフトウェアであるため、これらのJVMヒープ、スタック、スレッドは物理マシンにどのようにマッピングされるのかということです。

ヒープは、事前に割り当てられた仮想メモリの連続領域です。例えば.

 void* heap = malloc(Xmx); // get the maximum size.

スタックは、スレッドの開始時にスレッドライブラリによって割り当てられます。繰り返しますが、これは最大スタックサイズである仮想メモリの連続した領域です。再びあなたはそれを次のように考えることができます

 void* stack = malloc(Xss); // get the maximum stack size.

ネイティブスレッドは、JVMスペース自体の一部ではないOS機能です。

JavaはJVMで実行されますが、C++では実行されません。

C++を起動するには、まだランタイム環境とライブラリが必要です。 C++ランタイムまたはlibcを削除してみてください。これらは起動しません。

Javaと比較すると、C++ランタイムデータ領域はどのように見えますか?

使用できる仮想メモリの大きな領域が1つあります。それはあなたに多くを語らないだろうので、写真はありません。ユーザースペースとラベル付けされた1つの長い長方形を想像してください。

JVMのヒープ、スタック、レジスタ、スレッドはどのようにオペレーティングシステムにマッピングされますか?または私はそれらが物理マシンにどのようにマッピングされるのか尋ねるべきですか?

再び魔法はありません。 JVMヒープはメモリの領域であり、JVMスタックはC +が使用するネイティブスタックと同じであり、JVMのレジスタはC +が使用するネイティブレジスタと同じであり、JVMスレッドは実際にC +が使用するネイティブスレッドです。

私はあなたがより多くの魔法や不明瞭さがあると仮定していると思います。代わりに、最も単純で効率的で軽量な設計が使用されていることを前提とする必要があります。

物理マシンにどのようにマッピングされるのか尋ねる必要がありますか?

基本的に1対1。

36
Peter Lawrey