深入理解JVM的安全点与安全区域

在JVM中,"世界暂停"(Stop-The-World, STW)是一个很重要的机制。像垃圾回收(GC)这样的核心操作,都要求在一个数据一致的、静止的快照上进行。为了获取这个快照,JVM必须暂停所有正在运行的业务线程。

但是,这个"暂停"操作不能在任意指令上执行,否则可能导致数据处于不一致的状态。为了能够安全、高效地暂停所有线程,JVM设计了一套协作机制,其核心就是"安全点"(Safepoint)和"安全区域"(Safe Region)。

安全点:处理活跃执行的线程

安全点是代码执行流中的一些特定位置。它主要解决的是那些正在CPU上活跃执行的线程如何安全停下的问题。

当JVM需要STW时,它会设置一个全局标志。但它不会立即抢占式地中断线程,而是让这些活跃线程继续执行,直到它们运行到下一个安全点。到达这个特定位置时,线程会主动检查那个全局标志。如果发现需要暂停,它就会保存好上下文,然后主动挂起。

这些安全点的位置并不是随意设置的。JVM并不会在每条字节码后都设置,那样性能开f_da过高。它是在JIT编译时,在一些关键位置插入轮询指令,例如方法调用返回之前,或长时间循环的末尾。这样既能保证线程总会执行到安全点,也控制了性能损耗。

安全区域:协同非活动状态的线程

安全点机制依赖线程主动执行指令去轮询。但如果一个线程当前没有在CPU上执行,它就无法主动到达安全点。

例如,线程可能处于 BLOCKED 状态(等待锁),或者 WAITING 状态(执行了 Object.wait()),也可能正在执行JNI本地方法,此时执行控制权不在JVM。

"安全区域"就是为了处理这类非活动线程而设计的。安全区域是指代码中的一段连续区间,在这段代码执行期间,线程对Java堆中对象的引用关系保证不会发生任何变化。

它的协作流程是:当一个线程将要进入这种非活动状态(如发起JNI调用)之前,它会先标记自己的状态,表明将进入安全区域。

当JVM发起STW时,它会扫描所有线程。如果发现一个线程被标记为"在安全区域内",JVM就知道该线程的引用关系是稳定的,可以不等待它,直接将其视为已暂停。

当该线程完成了操作(如JNI调用返回),准备离开安全区域时,它不能立即恢复执行。它必须先检查JVM的全局STW标志位。如果STW正在进行中,该线程必须自我阻塞,在原地等待,直到STW结束的信号传来,它才能安全地离开。

总结:两者的关系

安全点和安全区域是JVM为实现STW而设计的两个互补的协作机制,共同确保所有应用线程都能在一个一致的状态下暂停。

  • 安全点主要面向正在CPU上活跃执行的线程。它通过JIT在代码中插入轮询点,让这些活跃线程主动在预设的安全位置上自我挂起。
  • 安全区域则解决了处于非活动状态的线程的协同问题,例如那些被阻塞、等待或正在执行本地代码的线程。通过标记进入和检查离开的机制,安全区域确保了JVM在STW时可以不必等待它们,同时也保证了它们在恢复运行时不会破坏内存一致性。

总而言之,安全点解决了活跃线程的暂停问题,而安全区域解决了非活跃线程的协同问题。两者共同作用,才使得JVM能够安全、完整地暂停所有应用线程。

相关推荐
yufuu981 小时前
使用Scikit-learn进行机器学习模型评估
jvm·数据库·python
darkb1rd1 小时前
二、PHP 5.4-7.4版本演进与安全改进
安全·php·webshell
珠海西格1 小时前
远动通信装置为何是电网安全运行的“神经中枢”?
大数据·服务器·网络·数据库·分布式·安全·区块链
格林威2 小时前
Baumer相机铸件气孔与缩松识别:提升铸造良品率的 6 个核心算法,附 OpenCV+Halcon 实战代码!
人工智能·opencv·算法·安全·计算机视觉·堡盟相机·baumer相机
小旭95272 小时前
Java 反射详解
java·开发语言·jvm·面试·intellij-idea
HalvmånEver2 小时前
Linux:线程创建与终止上(线程五)
java·linux·jvm
m0_706653233 小时前
Python入门:从零到一的第一个程序
jvm·数据库·python
K·Herbert3 小时前
OpenClaw 私人电脑部署风险
人工智能·安全·编辑器
2301_765703143 小时前
Python数据库操作:SQLAlchemy ORM指南
jvm·数据库·python
2301_790300963 小时前
深入理解Python的if __name__ == ‘__main__‘
jvm·数据库·python