JVM在停止世界暂停期间用于阻止线程的机制

时间:2013-05-15 07:01:55

标签: garbage-collection jvm

我在接受采访时听到了这个问题,无法提供答案。后来我通过互联网搜索,仍然没有找到答案。任何人都可以告诉我,在收集垃圾时,JVM如何在停止世界暂停期间停止线程以及它如何再次运行它们。

1 个答案:

答案 0 :(得分:15)

至少对于HotSpot和OpenJDK,JVM使用安全点来停止每个线程中的应用程序流,或者在JITed代码中引入,或者通过更改解释代码的字节码映射(请参阅Alexh Ragozin的this post for更多细节)。

请参阅Gil Tene的this answer,了解为什么在处理世界各地的停顿时,安全点可能是另一个问题。


基于上述资源,以下是Hotspot / OpenJDK中的安全点机制(参见例如safepoint.cpp,第154行)的更多细节(据我理解,我并不自称是专家) ,可能还有Cliff的一些文章点击Azul Systems博客(似乎已经从网站上消失了)。

到达安全点

JVM需要控制来自应用程序的流,因此它取决于线程的当前状态:

  • <强>阻止

    JVM已经控制了该线程。

  • 运行已解释的代码

    解释器进入一种模式(通过交换其调度表),其中每个字节码评估之前都会进行安全点检查。

  • 运行本机代码(JNI)

    JNI代码在安全点运行并且可以继续运行,除非它回调到Java或调用某些特定的JVM方法,此时可能会停止它以防止离开安全点(感谢Nitsan的注释)。

  • 运行已编译的代码

    JVM使特定的内存页面(Safepoint Polling页面)不可读,这使得定期读取该页面(由JIT编译器插入到编译的代码中)失败并转到JVM处理程序。

    < / LI>
  • 在VM中运行或转换状态(在VM中也是如此)

    无论如何,流程都会通过安全点检查,因此VM会等待它。

在安全点停止

一旦线程处于由JVM控制的安全点,JVM就会阻止它退出。当所有线程都已停止(即世界停止)时,JVM可以执行垃圾收集,然后释放所有恢复执行的线程。

有关更多详细信息,您可以在此期间阅读Nitsan Wakart撰写的blog post on safepoints(其本身有更多参考资料)。