{"name":"JAVA内存模型","id":"编程语言-JAVA-JVM-JAVA内存模型","content":"# JAVA 内存模型（JMM）\n\n> **并发的本质不是“多线程”，而是“在不确定执行顺序下，仍然保持因果一致性”。**\n\n* JMM 解决的根本问题是什么？\n* JMM 的最小抽象模型是什么？\n* JMM 如何在不可靠的硬件现实之上，构造一个“可被程序员理解的并发世界”？\n\n---\n\n## 一、问题定义：为什么需要 Java 内存模型（Why）\n\n### 1.1 并发的第一性问题\n\n在并发系统中，真正的问题并不是：\n\n* 线程是否同时执行\n\n而是：\n\n* **一个线程对共享状态的修改，是否、何时、以何种顺序，被另一个线程观察到**\n\n这三个问题可抽象为：\n\n> **可见性（Visibility） + 有序性（Ordering） + 原子性（Atomicity）**\n\n如果没有统一约束：\n\n* 不同 CPU 架构\n* 不同缓存一致性协议\n* 不同编译器优化策略\n\n将导致：\n\n* 同一段 Java 程序，在不同机器上语义不同\n\n---\n\n### 1.2 为什么“硬件一致性”不等于“程序一致性”\n\n现代计算机通过 **多级缓存 + 指令乱序执行** 提升性能：\n\n* 每个 CPU 核心有私有缓存\n* 写入并不立即对其他核心可见\n* 指令可能被重排序，只要不影响单线程结果\n\n**硬件的一致性目标是“最终一致 + 高性能”**，而不是：\n\n* 为高级语言提供确定的并发语义\n\n👉 **JMM 的使命**：\n\n> 在不可信的硬件与编译器优化之上，\n> 为 Java 程序员提供一个**确定、可推理的并发语义模型**。\n\n---\n\n## 二、JMM 的抽象模型（What）\n\n### 2.1 JMM 的定位\n\n必须首先澄清一个关键误区：\n\n> **JMM ≠ JVM 内存结构**\n\n| 维度  | JMM       | JVM 内存结构 |\n| --- | --------- | -------- |\n| 性质  | 抽象规范      | 具体实现     |\n| 关注点 | 并发语义      | 内存分配     |\n| 目标  | 可见性 / 有序性 | 运行效率     |\n\nJMM 是：\n\n> **JVM 必须遵守的并发语义契约**\n\n而不是：\n\n* 堆 / 栈 / 方法区的划分说明\n\n---\n\n### 2.2 主内存 / 工作内存：最小并发抽象\n\nJMM 用一个**极简但足够表达并发问题的模型**描述内存：\n\n* **主内存（Main Memory）**：\n\n  * 所有线程共享的变量视图\n* **工作内存（Working Memory）**：\n\n  * 线程私有\n  * 保存主内存变量的副本\n\n关键约束：\n\n* 线程不能直接读写主内存\n* 线程间通信 **只能通过主内存完成**\n\n> 工作内存不是 JVM 的某个内存区域，\n> 而是对 **CPU 缓存 / 寄存器 / 编译器暂存** 的抽象。\n\n---\n\n### 2.3 happens-before：JMM 的核心抽象\n\n#### 2.3.1 happens-before 的本质\n\nhappens-before **不是时间先后关系**，而是：\n\n> **可见性与有序性的因果约束关系（Partial Order）**\n\n含义只有一个：\n\n> 如果 A happens-before B，\n> 那么 A 的结果 **对 B 可见**，并且 A 的执行顺序 **排在 B 之前**。\n\n如果两个操作之间 **不存在 happens-before 关系**：\n\n* JVM 可以自由重排序\n* 读取到任意历史值都是合法的\n\n👉 **这不是 Bug，而是未定义并发语义**。\n\n---\n\n#### 2.3.2 happens-before 的\"天然规则\"\n\n这些规则并不是语法糖，而是 **并发因果的基本公理**：\n\n* 单线程顺序规则\n* 锁的释放 → 锁的获取\n* volatile 写 → volatile 读\n* 线程启动 / 结束 / join\n* 中断规则\n* 构造完成 → finalize\n* 传递性\n\n> happens-before 规则集合 = JMM 的最小公理系统\n\n---\n\n### 2.4 as-if-serial 语义\n\nJMM 允许大量重排序优化，但有一条不可打破的底线：\n\n> **在单线程语义下，执行结果必须\"看起来像是顺序执行的\"**\n\n这条规则：\n\n* 约束编译器\n* 约束 CPU\n* 保证单线程世界的确定性\n\n---\n\n## 三、JMM 的并发三特性（模型层）\n\n### 3.1 原子性\n\n* JMM 保证基本内存操作的原子性\n* 对 64 位数据（long / double）允许拆分（非 volatile）\n\n👉 原子性不是\"操作不可分\"，而是：\n\n> **在并发可观察层面，不可被中途观察到**\n\n---\n\n### 3.2 可见性\n\n可见性 = 写入结果 **是否能被其他线程感知**\n\nJMM 提供三种\"可见性通道\"：\n\n* volatile\n* synchronized（unlock → 主内存刷新）\n* final（构造安全发布）\n\n---\n\n### 3.3 有序性\n\n* 单线程：天然有序\n* 多线程：除非建立 happens-before，否则无序\n\n指令重排序：\n\n* 不破坏单线程语义\n* 但可能破坏并发直觉\n\n---\n\n## 四、JMM 的实现手段（How）\n\n> **JMM 不关心\"怎么实现\"，但 JVM 必须用现实世界的工具去兑现语义承诺。**\n\n---\n\n### 4.1 volatile：轻量级因果约束\n\n语义本质：\n\n* 建立 **写 → 读 的 happens-before**\n* 禁止相关指令重排序\n\n实现层次：\n\n* 字节码：ACC_VOLATILE\n* JVM：插入内存屏障\n* 硬件：cache flush / fence / lock 指令\n\n适用场景：\n\n* 状态标志\n* 单写多读\n* 不依赖复合不变式\n\n---\n\n### 4.2 synchronized：强因果封闭区\n\n语义本质：\n\n* 构造 **临界区的全序执行视图**\n\n实现层次：\n\n* 字节码：monitorenter / monitorexit\n* JVM：对象监视器\n* OS / CPU：原子指令\n\n价值：\n\n* 不只是互斥，而是 **内存语义的边界封装**\n\n---\n\n### 4.3 内存屏障：语义兑现工具\n\n内存屏障不是给程序员用的，而是：\n\n* JVM 对硬件下达的\"秩序约束指令\"\n\n屏障类型：\n\n* LoadLoad\n* StoreStore\n* LoadStore\n* StoreLoad\n\n---\n\n## 五、工程视角：如何\"用对\"JMM\n\n### 5.1 用 happens-before 思考并发，而不是\"先加锁\"\n\n设计并发代码的核心问题应是：\n\n> 我是否明确建立了线程间的因果关系？\n\n---\n\n### 5.2 JMM 不能替你解决的问题\n\n* 复合操作的一致性\n* 业务不变式\n* 高层并发策略\n\nJMM 只是：\n\n> **并发世界的物理定律，而不是业务逻辑的守护神**\n\n---\n\n## 六、演进与对比视角（长期价值）\n\n* JSR-133：确立现代 JMM\n* Java 内存模型：相对\"强\"的语言级模型\n* 对比 C/C++：Java 用性能换可推理性\n\n## 关联内容（自动生成）\n\n- [/编程语言/JAVA/JAVA并发编程/基础概念.md](/编程语言/JAVA/JAVA并发编程/基础概念.md) 涵盖了Java并发编程的基本概念，包括原子性、可见性、有序性等与JMM密切相关的特性\n- [/编程语言/JAVA/JAVA并发编程/JAVA并发编程.md](/编程语言/JAVA/JAVA并发编程/JAVA并发编程.md) 介绍了Java并发编程的整体概念，与JMM作为Java并发语义基础密切相关\n- [/编程语言/JAVA/JAVA并发编程/线程池.md](/编程语言/JAVA/JAVA并发编程/线程池.md) 线程池是Java并发编程的重要组成部分，其设计和实现与JMM的内存可见性和线程同步机制密切相关\n- [/编程语言/JAVA/JAVA并发编程/并发集合.md](/编程语言/JAVA/JAVA并发编程/并发集合.md) 并发集合的实现依赖于JMM提供的内存模型和同步机制，是JMM在实际开发中的重要应用\n- [/编程语言/JAVA/JAVA并发编程/并发工具类.md](/编程语言/JAVA/JAVA并发编程/并发工具类.md) Java并发工具类的实现基于JMM提供的同步原语，是JMM在实际开发中的具体体现\n- [/编程语言/并发模型.md](/编程语言/并发模型.md) 探讨了不同编程语言中的并发模型，有助于理解JMM在并发编程语言设计中的地位和作用\n- [/操作系统/内存管理.md](/操作系统/内存管理.md) 操作系统内存管理机制是JMM实现的基础，理解底层内存管理有助于深入理解JMM的设计原理\n","metadata":"tags: ['编程语言', '并发编程', '性能']","hasMoreCommit":true,"totalCommits":18,"commitList":[{"date":"2026-02-12T14:07:03+08:00","author":"MY","message":"doc: 整理标签","hash":"290b3e8ad18f48832ac282290238d020fc030a88"},{"date":"2026-01-08T11:22:39+08:00","author":"MY","message":"docs(JAVA): 更新JMM内存模型文档内容","hash":"f79136e8993e13c8d05a4fb989391a03fa2c5bcc"},{"date":"2024-11-19T11:17:02+08:00","author":"MY","message":"📦JMM","hash":"348d7c9c4dc4490c0016c6bcdf89ae8cbabaee23"},{"date":"2024-03-05T20:06:31+08:00","author":"MY","message":"✏内存","hash":"8f9e10b4889ef382f9556d7898c1a175490291df"},{"date":"2023-08-22T20:11:31+08:00","author":"MY","message":"✏JVM","hash":"27a8c0f6b164c2450492b9fddf6be4efb8262183"},{"date":"2022-07-07T21:53:14+08:00","author":"MY","message":"✏️更新 并发与底层","hash":"b99a8b8e7cd5b351f7553f7ab8d2d5b9b76f8a5b"},{"date":"2022-04-20T14:24:03+08:00","author":"cjiping","message":"✏️更新 JMM","hash":"70e4f77283b8dc4f720cc7d88b5c84d949466539"},{"date":"2022-03-04T17:08:43+08:00","author":"cjiping","message":"✏️更新 JAVA并发编程","hash":"7c91a0de9f5ef8f32618b700ac4b57a933f9e1e7"},{"date":"2021-04-12T14:35:08+08:00","author":"cjiping","message":"✏更新 volatile","hash":"95d9dfe55e8c3289b722f1e25f9ea412a2c6ae73"},{"date":"2021-04-09T17:28:17+08:00","author":"cjiping","message":"✏更新 JMM","hash":"98dd2463d585ac8a7cd52f1f67c088422c420f5d"}],"createTime":"2019-12-29T22:21:17+08:00"}