Java 中怎么理解硬件级内存屏障指令(lfence、sfence、mfence)在 JVM 底层的具体映射

千磊君_7017

千磊君_7017

2026-08-15

484人浏览

原创

Java内存模型通过JVM将抽象内存屏障映射为硬件指令:x86下LoadLoad/LoadStore通常无需指令,StoreStore可能用sfence,StoreLoad必用mfence或lock空操作;ARM下各类屏障均需dmb指令。

java 中怎么理解硬件级内存屏障指令(lfence、sfence、mfence)在 jvm 底层的具体映射

Java 程序员通常不直接写 lfence、sfence 或 mfence,但这些指令确实在 JVM 底层真实存在,并被悄悄插入到生成的机器码中——它们是 Java 内存模型(JMM)落地为硬件行为的关键桥梁。

JVM 不暴露硬件指令,而是通过 内存屏障抽象(如 LoadLoad、StoreStore 等)来表达语义,再由 JIT 编译器根据运行时 CPU 架构,把抽象屏障映射为对应平台的实际指令。


x86 平台下 JVM 如何映射内存屏障

x86 是强内存模型,重排序限制较严,但仍需屏障控制:

  • LoadLoad 和 LoadStore → 通常 不需要指令(x86 天然保证 Load 不会越过 Load 或 Store)
  • StoreStore → 编译器可能省略,但若涉及非易失性写或跨缓存行操作,JIT 可能插入 sfence
  • StoreLoad → 这是最关键也最昂贵的屏障,在 x86 上 必须用 mfence(或 lock addl $0, (%rsp) 这类带 lock 前缀的空操作)
    • 因为 x86 允许 Store 后面的 Load 提前执行(Store-Load 重排序),而 JMM 要求 volatile 写后读必须看到最新值,所以此处强制全屏障

举例:volatile int flag = 1; 后紧跟 int x = data;,JVM 在 flag = 1 后插入 mfence,确保 data 的读不会提前到 flag 写之前。


ARM 平台下的映射更频繁且语义不同

ARM 是弱内存模型,几乎每个屏障抽象都需显式指令:

  • LoadLoad → dmb ishld(数据内存屏障,仅约束 Load)
  • StoreStore → dmb ishst(仅约束 Store)
  • LoadStore / StoreLoad → dmb ish(全屏障,类似 x86 的 mfence)
  • dsb sy 则用于更强同步(如线程退出、锁释放后刷新所有缓存)

JVM 在 ARM 上不会省略屏障,哪怕只是 volatile 读写,也会生成对应 dmb 指令 —— 因为硬件不保证顺序,必须靠指令显式约束。

java-api-doc-generator
java-api-doc-generator

分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。

下载

JVM 怎么决定插哪条指令?

核心逻辑在 OrderAccess 类和平台相关汇编生成器中:

  • JIT 编译时,根据当前指令序列的 JMM 抽象屏障类型 + 目标 CPU 架构 查表匹配
  • 例如:OrderAccess::storestore() 在 x86_64 下可能展开为空或 sfence;在 aarch64 下一定生成 dmb ishst
  • volatile 字段访问、synchronized 退出、Unsafe.storeFence() 等都会触发对应屏障插入点

你可以在 -XX:+PrintAssembly 输出中看到类似:

movl $1, %eax
movl %eax, 0x10(%rip)      # volatile write
mfence                     # <hr><h3>注意:lock 前缀不是屏障,但效果等价</h3><p><code>lock addl $0, (%rsp)</code> 这类指令在 x86 上常被用作 <code>StoreLoad</code> 替代方案,因为:</p>
  • 它隐含全内存屏障语义(锁总线/缓存行)
  • 比 mfence 更轻量(尤其在老 CPU 上)
  • JVM 在某些场景(如 Unsafe.fullFence())会优先选 lock 空操作而非 mfence

但它本质是原子指令,不是屏障指令 —— 只是“恰好”达成屏障效果。

不复杂但容易忽略

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

11877

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

8982

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

7692

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1264

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

1008

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1516

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

3109

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20371

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1355

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习