容易混淆的东西:JVM内存模型和JMM

133 阅读2分钟

容易混淆的东西:JVM内存模型和JMM

  • JVM内存模型和JVM运行时区域有关
  • Java内存模型和Java并发编程有关(JMM)

这两个是有很大区别的!!

JVM内存模型想必大家都很清楚了

Java代码->CPU指令

Java代码最终还是要转化为CPU指令才能执行

上图

在这里插入图片描述

在更早期的语言中,其实是不存在内存模型的概念的。

所以程序最终执行的效果会依赖于具体的处理器,而不同的处理器的规则又不一样,不同的处理器之间可能差异很大,因此同样的一段代码,可能在处理器 A 上运行正常,而在处理器 B 上运行的结果却不一致。同理,在没有 JMM 之前,不同的 JVM 的实现,也会带来不一样的 “翻译” 结果。

所以 Java 非常需要一个标准,来让 Java 开发者、编译器工程师和 JVM 工程师能够达成一致。达成一致后,我们就可以很清楚的知道什么样的代码最终可以达到什么样的运行效果,让多线程运行结果可以预期,这个标准就是 JMM,这就是需要 JMM 的原因。

JMM

JMM 是和多线程相关的一组规范,需要各个 JVM 的实现来遵守 JMM 规范,以便于开发者可以利用这些规范,更方便地开发多线程程序。这样一来,即便同一个程序在不同的虚拟机上运行,得到的程序结果也是一致的。

如果没有 JMM 内存模型来规范,那么很可能在经过了不同 JVM 的 “翻译” 之后,导致在不同的虚拟机上运行的结果不一样,那是很大的问题

因此JMM与处理器、缓存、并发、编译器有关,它解决了CPU多级缓存、处理器优化、指令重排序的结果不可预期的问题

JMM是工具类和关键字的原理

之前我们使用了各种同步工具和关键字,包括 volatile、synchronized、Lock 等,其实它们的原理都涉及 JMM。正是 JMM 的参与和帮忙,才让各个同步工具和关键字能够发挥作用,帮我们开发出并发安全的程序。

比如我们写了关键字 synchronized,JVM 就会在 JMM 的规则下,“翻译” 出合适的指令,包括限制指令之间的顺序,以便在即使发生了重排序的情况下,也能保证必要的 “可见性”,这样一来,不同的 JVM 对于相同的代码的执行结果就变得可预期了,我们 Java 程序员就只需要用同步工具和关键字就可以开发出正确的并发程序了,这都要感谢 JMM。

JMM最重要3个部分:重排序、原子性、内存可见性