私が正しく理解している場合、スタックはローカルプリミティブとヒープ内のオブジェクトへの参照用です。では、スレッドが複数ある場合はどうなるでしょうか。
それらは同時に同じスタック スペースを共有しますか (ただし領域は異なります)、それともスレッド間の切り替え時に JRE がコンテキストを切り替えてスタック コンテンツをロード/デロードしますか?
それとも、JRE はスレッドごとに個別のスタックを割り当てますか?
私が正しく理解している場合、スタックはローカルプリミティブとヒープ内のオブジェクトへの参照用です。では、スレッドが複数ある場合はどうなるでしょうか。
それらは同時に同じスタック スペースを共有しますか (ただし領域は異なります)、それともスレッド間の切り替え時に JRE がコンテキストを切り替えてスタック コンテンツをロード/デロードしますか?
それとも、JRE はスレッドごとに個別のスタックを割り当てますか?
それとも、JRE はスレッドごとに個別のスタックを割り当てますか?
概念的にはい。(たとえば、このJVM 仕様のリンクを参照してください。)
仕様の概念化が特定の JVM でどのように実装されるかは、実装固有です。ただし、私の理解では、現在の世代 (Hotspot など) の JVM は、OS から要求されたメモリの個別のブロックに各スレッド スタックを割り当てます。たとえば、mmap
syscall 1を使用します。
スレッドの切り替えが発生したときに、スタックの内容が大量にコピーされることはありません。ただし、スレッド コンテキストの切り替えには、レジスタの保存と読み込み、および (間接的に) メモリ キャッシュと TLB エントリへの余分な読み込みが必要です。これは重大な問題になる可能性があります...これが、過剰なスレッド コンテキストの切り替え (たとえば、ロックの競合や過剰な待機/通知によって引き起こされる) がパフォーマンスに悪影響を与える可能性がある理由です。
1 - 私の記憶では、一部の JVM には、各スタック セグメントの最後に読み取り専用の「レッド ゾーン」ページが含まれています。(これは、スレッド スタック オーバーフローがメモリ障害を引き起こし、JVM が各メソッド呼び出しでスタック オーバーフローを明示的にチェックする必要がないことを意味します。これは、パフォーマンスに大きな影響を与えます。) " ページでは、mmap を使用してスレッド スタックを要求する必要があります。
各スレッドには、そのスレッドで実行される各メソッドのフレームを保持する独自のスタックがあります。これは、「スレッドごと」のセクションで確認できます。
Java スレッドはスレッド オブジェクトで表され、各スレッドには実行時データの格納に使用される個別のスレッド スタックが割り当てられます。スレッド スタックには特定のサイズがあります (VM オプションを使用して設定できますjava -Xss1m Application
)。
実行時に、スレッドがスタック サイズが許容するよりも多くの日付を格納しようとすると、スタック オーバーフロー エラーが発生します。