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),从而影响系统的响应性。