56

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

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

ここに画像の説明を入力

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

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

誰かがJavaとC ++の間でそれらの概念を比較できれば幸いです。Java は JVM で実行されますが、C++ は実行されないためです。

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

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

更新:プロセスの実行時物理メモリの絵を描きます。
ここに画像の説明を入力

4

1 に答える 1

39

私が理解できないのは、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。

于 2013-04-28T16:58:57.430 に答える