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

相关推荐
f***68602 小时前
【Sql Server】sql server 2019设置远程访问,外网服务器需要设置好安全组入方向规则
运维·服务器·安全
安科瑞刘鸿鹏172 小时前
从监测到保护:ALP如何赋能企业配电柜安全升级?
运维·网络·安全
2501_941111402 小时前
使用Scrapy框架构建分布式爬虫
jvm·数据库·python
麦兜*3 小时前
Redis内存消耗异常飙升?深入排查与Big Key/Hot Key的根治方案
jvm·数据库·spring boot·redis·spring·缓存
Andya_net3 小时前
网络安全 | 深入理解SQL注入的原理和防范
sql·安全·web安全
2501_941111824 小时前
使用Python进行网络设备自动配置
jvm·数据库·python
T***16075 小时前
免费的Web安全漏洞利用,Metasploit教程
安全·web安全
武汉唯众智创5 小时前
职业院校网络安全靶场实训演练系统建设方案
网络·安全·web安全·网络安全·网络安全靶场实训演练系统·网络安全靶场实训·网络安全实训演练系统
盈创力和20075 小时前
北斗形变监测仪:高精度结构安全的“守护之眼”
安全·变形监测·地质灾害监测·北斗形变监测仪·楼宇变形监测·桥梁隧道公路变形监测·水利安全监测
奋进的电子工程师5 小时前
如何实现开源组件的安全与合规治理?
安全·开源·代码规范·设计规范·代码复审