面接でこの質問を聞いたのですが、答えられませんでした。後でインターネットで検索しましたが、やはり答えは見つかりませんでした。ガベージ収集時に JVM がストップザワールド一時停止中にスレッドを停止し、再び実行する方法を教えていただけませんか。
ベストアンサー1
少なくともHotSpotとOpenJDKでは、JVMは各スレッドでアプリケーションのフローを停止するためにセーフポイントを使用します。これは、JITコードで導入されるか、解釈されたコードのバイトコードマッピングを変更することによって行われます(この郵便受け詳細については、Alexey Ragozin の著書をご覧ください。
参照この答えGil Tene による、stop-the-world 一時停止を処理するときにセーフポイントが追加の問題になる可能性がある理由について説明します。
Hotspot/OpenJDKのセーフポイント機構に関する詳細は、こちら(私が理解している限りでは、専門家であると主張するものではありません)をご覧ください(例えば、セーフポイント.cpp、154行目)、上記のリソースとおそらくクリフによるいくつかの記事に基づいて、アズールシステムズブログ(サイトからは消えてしまったようです)。
セーフポイントに到達
JVM はアプリケーションからフローを制御する必要があるため、スレッドの現在の状態に依存します。
ブロックされました
JVM はすでにそのスレッドを制御しています。
解釈されたコードの実行
インタープリタは、ディスパッチ テーブルを交換することによって、各バイトコードの評価の前にセーフポイント チェックが行われるモードになります。
ネイティブコードの実行(JNI)
JNI コードはセーフポイントで実行され、Java にコールバックしたり、特定の JVM メソッドを呼び出したりしない限り、実行を継続できます。その時点で、セーフポイントを離れないように停止されることがあります (コメントをくれた Nitsan に感謝します)。
コンパイルされたコードの実行
JVM は特定のメモリ ページ (Safepoint Polling ページ) を読み取り不可にします。これにより、そのページ (JIT コンパイラによってコンパイルされたコードに挿入される) の定期的な読み取りが失敗し、JVM ハンドラーに渡されます。
VM 内で実行中または状態遷移中(VM 内でも)
いずれにしても、フローはある時点でセーフポイント チェックを通過するため、VM はそれを待機します。
セーフポイントで停止
スレッドが JVM によって制御されるセーフポイントに到達すると、JVM はスレッドの終了をブロックするだけです。すべてのスレッドが停止すると (つまり、世界が停止すると)、JVM はガベージ コレクションを実行し、実行を再開するすべてのスレッドを解放できます。
詳細は、こちらをお読みくださいセーフポイントに関するブログ投稿その間に Nitsan Wakart によって書かれました (それ自体さらに多くの参照があります)。