19

我在一次采访中听到了这个问题,无法提供答案。后来我通过互联网搜索,仍然没有找到答案。谁能告诉我 JVM 在收集垃圾时如何在 stop-the-world 暂停期间停止线程以及它如何再次运行它们。

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 回答