深入理解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能够安全、完整地暂停所有应用线程。

相关推荐
黎阳之光5 小时前
黎阳之光:视频孪生领跑者,铸就中国数字科技全球竞争力
大数据·人工智能·算法·安全·数字孪生
上海云盾-高防顾问5 小时前
网络安全防护发展趋势:从被动防御到主动赋能
安全·web安全
彧翎Pro5 小时前
基于 RO1 noetic 配置 robosense Helios 32(速腾) & xsense mti 300
前端·jvm
CCTI_Curran6 小时前
UL4200A是美国针对纽扣电池安全标准
安全·纽扣电池·ul4200a·纽扣电池gcc认证·美国亚马逊
做个文艺程序员6 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
是罐装可乐6 小时前
深入理解“句柄(Handle)“:从浏览器安全到文件系统访问
前端·javascript·安全
Figo_Cheung7 小时前
Figo义商本体约束推理引擎 (CRE):基于已部署CRE本地模型的技术实践研究——迈向AGI时代的AI伦理安全框架
人工智能·安全
信创DevOps先锋8 小时前
DevOps工具链选型新趋势:本土化适配与安全可控成企业核心诉求
运维·安全·devops
ayt0078 小时前
Netty AbstractNioChannel源码深度剖析:NIO Channel的抽象实现
java·数据库·网络协议·安全·nio
minji...9 小时前
Linux 线程同步与互斥(二) 线程同步,条件变量,pthread_cond_init/wait/signal/broadcast
linux·运维·开发语言·jvm·数据结构·c++