SafePoint(安全点)是JVM(Java虚拟机)中的一个重要概念,它是程序执行过程中的一些特殊位置,在这些位置上,JVM可以安全地暂停所有线程,以便执行一些需要全局一致状态的操作,比如垃圾回收(GC)代码反优化线程栈 dump 等。

SafePoint 的作用

  • 线程暂停

    • 当JVM需要执行一些全局操作(如GC)时,必须确保所有线程都处于一个一致的状态;

    • SafePoint 是线程可以安全暂停的位置,线程在 SafePoint 处暂停后,JVM 可以安全地操作线程的栈、寄存器等状态。

  • 避免状态不一致

    • 如果线程在非 SafePoint 处被暂停,可能会导致不一致的状态(例如,对象引用关系不明确),从而影响垃圾回收的正确性。

SafePoint 的触发条件

  • 方法调用

    • 在方法调用时,JVM 会插入一个 SafePoint。

  • 循环回边

    • 在循环的末尾(回边),JVM 会插入一个 SafePoint,以便长时间运行的循环能够定期检查是否需要进入 SafePoint。

  • 显式请求

    • 当 JVM 需要执行全局操作(如 GC)时,会请求所有线程进入 SafePoint。

SafePoint 的实现

  • 主动式 SafePoint

    • 线程在执行到 SafePoint 时,会主动检查是否需要暂停,这种方式需要编译器在代码中插入 SafePoint 检查指令。

  • 被动式 SafePoint

    • JVM 通过信号机制(如 POSIX 信号)中断线程,强制其进入 SafePoint,这种方式不需要编译器插入额外的指令,但可能会引入一些性能开销。

SafePoint 的性能影响

  • SafePoint 检查会引入一定的性能开销,尤其是在高频率的循环中;

  • 现代 JVM 会优化 SafePoint 的插入频率,以减少对性能的影响;

  • 如果线程长时间运行而不进入 SafePoint(例如,执行一个非常长的循环),可能会导致 JVM 无法及时执行全局操作(如 GC),从而影响系统的响应性。