集体创作公约:自己申明创作的所有文章皆为本人原创,如果有参考任何文章的中央,会标注进去,如果有疏漏,欢送大家批评。如果大家发现网上有剽窃本文章的,欢送举报,并且踊跃向这个 github 仓库 提交 issue,谢谢反对~
本篇文章参考了大量文章,文档以及论文,然而这块货色真的很繁冗,我的程度无限,可能了解的也不到位,如有异议欢送留言提出。 本系列会不断更新,联合大家的问题以及这里的谬误和疏漏,欢送大家留言
如果你喜爱单篇版,请拜访:全网最硬核 Java 新内存模型解析与试验单篇版(不断更新 QA 中)
如果你喜爱这个拆分的版本,这里是目录:
- 全网最硬核 Java 新内存模型解析与试验 – 1. 什么是 Java 内存模型
- 全网最硬核 Java 新内存模型解析与试验 – 2. 原子拜访与字决裂
- 全网最硬核 Java 新内存模型解析与试验 – 3. 硬核了解内存屏障(CPU+ 编译器)
- 全网最硬核 Java 新内存模型解析与试验 – 4. Java 新内存拜访形式与试验
- 全网最硬核 Java 新内存模型解析与试验 – 5. JVM 底层内存屏障源码剖析
JMM 相干文档:
- Java Language Specification Chapter 17
- The JSR-133 Cookbook for Compiler Writers – Doug Lea’s
- Using JDK 9 Memory Order Modes – Doug Lea’s
内存屏障,CPU 与内存模型相干:
- Weak vs. Strong Memory Models
- Memory Barriers: a Hardware View for Software Hackers
- A Detailed Analysis of Contemporary ARM and x86 Architectures
- Memory Model = Instruction Reordering + Store Atomicity
- Out-of-Order Execution
x86 CPU 相干材料:
- x86 wiki
- Intel® 64 and IA-32 Architectures Software Developer Manuals
- Formal Specification of the x86 Instruction Set Architecture
ARM CPU 相干材料:
- ARM wiki
- aarch64 Cortex-A710 Specification
各种一致性的了解:
- Coherence and Consistency
Aleskey 大神的 JMM 解说:
- Aleksey Shipilëv – 不要误会 Java 内存模型(上)
- Aleksey Shipilëv – 不要误会 Java 内存模型(下)
置信很多 Java 开发,都应用了 Java 的各种并发同步机制,例如 volatile,synchronized 以及 Lock 等等。也有很多人读过 JSR 第十七章 Threads and Locks(地址:https://docs.oracle.com/javase/specs/jls/se17/html/jls-17.html),其中包含同步、Wait/Notify、Sleep & Yield 以及内存模型等等做了很多标准解说。然而也置信大多数人和我一样,第一次读的时候,感觉就是在看热闹,看完了只是晓得他是这么规定的,然而为啥要这么规定,不这么规定会怎么样,并没有很清晰的意识。同时,联合 Hotspot 的实现,以及针对 Hotspot 的源码的解读,咱们甚至还会发现,因为 javac 的动态代码编译优化以及 C1、C2 的 JIT 编译优化,导致最初代码的体现与咱们的从标准上了解出代码可能的体现是不太统一的。并且,这种不统一,导致咱们在学习 Java 内存模型(JMM,Java Memory Model),了解 Java 内存模型设计的时候,如果想通过理论的代码去试,后果是与本人原本可能正确的了解被带偏了,导致误会。
我自己也是一直地尝试了解 Java 内存模型,重读 JLS 以及各路大神的剖析。这个系列,会梳理我集体在浏览这些标准以及剖析还有通过 jcstress 做的一些试验而得出的一些了解,心愿对于大家对 Java 9 之后的 Java 内存模型以及 API 形象的了解有所帮忙。然而,还是强调一点,内存模型的设计,出发点是让大家能够不必关怀底层而形象进去的一些设计,波及的货色很多,我的程度无限,可能了解的也不到位,我会尽量把每一个论点的论据以及参考都摆出来, 请大家不要齐全置信这里的所有观点,如果有任何异议欢送带着具体的实例反驳并留言 。
1. 了解“标准”与“实现”
首先,我想先参考 Aleksey Shipilëv 大神的了解思路,即首先分分明标准(Specification)与实现(Implementation)的区别。后面提到的 JLS(Java Language Specification)其实就是一种标准,它标准了 Java 语言,并且所有能编译运行 Java 语言的 JDK 实现都要实现它外面规定的性能。然而对于理论的实现,例如 Hotspot JVM 的 JDK,就是具体的实现了, 从标准到理论的实现,其实是有肯定的差别的 。首先是上面这个代码:
理论 HotSpot 最初编译并且通过 JIT 优化与 CPU 指令优化运行的代码其实是:
行将后果 3 放入寄存器并返回,这样与原始代码其实成果是统一的,省略了无用的本地变量操作,也是正当的。那么你可能会有疑难:不会呀,我打断点运行到这里的时候,能看到本地变量 x,y,result 呀。这个其实是 JVM 运行时做的工作,如果你是以 DEBUG 模式运行 JVM,那么其实 JIT 默认就不会启用,只会简略的解释执行,所以你能看到本地变量。然而理论执行中,如果这个办法是热点办法,通过 JIT 的优化,这些本地变量其实就不存在了。
还有一个例子是,Hotspot 会有锁收缩机制(这个咱们前面还会测试),即:
如果依照 JLS 的形容,那么 x = 1 与 y = 1 这两个操作是不能重排序的。然而 Hotspot 理论的实现会将下面的代码优化成:
那么这样,其实 x = 1 与 y = 1 这两个操作就能够重排序了,这个咱们前面也会验证。
不同的 JVM 实现,理论的体现都会有些差别。并且就算是同一个 JVM 实现,在不同的操作系统,硬件环境等等,体现也有可能不一样。例如上面这个例子:
失常状况下,r1 的值应该只有 {-1, 0}
这两个后果之一。然而在某些 32 位的 JVM 上执行会有些问题,例如在 x86_32 的环境下,可能会有 {-1, 0, -4294967296, 4294967295}
这些后果。
所以,如果咱们要全面的笼罩底层到 JMM 设计以及 Hotspot 实现和 JIT 优化等等等等,波及的货色太多太多,一层逻辑套逻辑,八面玲珑我真的做不到。并且我也没法保障我了解的百分百精确。如果咱们要波及太多的 HotSpot 实现,那么咱们可能就偏离了咱们这个系列的主题, 咱们其实次要关怀的是 Java 自身内存模型的设计规范,而后从中总结出咱们在理论应用中,须要晓得并且留神的点的最小汇合 ,这个也是本系列要梳理的,同时,为了保障本系列梳理出的这个最小汇合精确,会加上很多理论测试的代码,大家也能够跑一下看看这里给出的论断以及对于 JMM 的了解是否正确。
微信搜寻“我的编程喵”关注公众号,加作者微信,每日一刷,轻松晋升技术,斩获各种 offer:
我会常常发一些很好的各种框架的官网社区的新闻视频材料并加上集体翻译字幕到如下地址(也包含下面的公众号),欢送关注:
- 知乎:https://www.zhihu.com/people/…
- B 站:https://space.bilibili.com/31…