19

インタビューでこの質問を聞いたのですが、答えられませんでした。その後、インターネットで検索しましたが、まだ答えが見つかりませんでした。ガベージを収集するときに JVM が停止中の一時停止中にスレッドを停止する方法と、それらを再実行する方法を教えてください。

4

1 に答える 1

17

少なくとも HotSpot と OpenJDK の場合、JVM はセーフ ポイントを使用して各スレッドでアプリケーションのフローを停止します。これは、JITed コードで導入されるか、解釈されたコードのバイトコード マッピングを変更することによって行われます (詳細については、Alexey Ragozin によるこの投稿を参照してください)。

ストップ・ザ・ワールドの一時停止を処理するときにセーフポイントが追加の問題になる可能性がある理由については、Gil Tene によるこの回答も参照してください。


Hotspot/OpenJDK のセーフポイント メカニズムの詳細を以下に示します (私が理解しているように、私は専門家ではありません) (たとえば、safepoint.cppの 154 行を参照)。上記のリソースに基づいています。 Cliff の記事Azul Systemsブログ (サイトから消えたようです) をクリックします。

セーフポイントに到達

JVM はアプリケーションからフローの制御を取得する必要があるため、スレッドの現在の状態に依存します。

  • ブロックされた

    JVM はすでにそのスレッドを制御しています。

  • 解釈されたコードの実行

    インタプリタは、各バイトコード評価の前にセーフポイント チェックが行われるモードに (ディスパッチ テーブルを交換することによって) 入ります。

  • ネイティブ コードの実行(JNI)

    JNIコードはセーフポイントで実行され、Javaにコールバックするか、特定のJVMメソッドを呼び出す場合を除き、実行を継続できます。その時点で、セーフポイントを離れるのを防ぐために停止する場合があります(コメントについてはNitsanに感謝します)。

  • コンパイル済みコードの実行

    JVM は特定のメモリ ページ (セーフポイント ポーリング ページ) を読み取り不能にします。これにより、そのページの定期的な読み取り (JIT コンパイラによってコンパイルされたコードに挿入される) が失敗し、JVM ハンドラーに送られます。

  • VM で実行中または遷移中の状態 (VM 内でも)

    とにかく、フローはある時点でセーフポイント チェックを通過するため、VM はそれを待ちます。

セーフポイントで停止

スレッドがセーフポイントに到達し、JVM によって制御されると、JVM は単純にスレッドの終了をブロックします。すべてのスレッドが停止した場合 (つまり、世界が停止した場合)、JVM はガベージ コレクションを実行し、すべてのスレッドを解放して実行を再開できます。

詳細については、当面の間、Nitsan Wakart によって書かれたセーフポイントに関するこのブログ投稿を参照してください (それ自体にはさらに多くの参照があります)。

于 2013-05-15T08:29:03.187 に答える