引入:
cpu和内存之间巨大的传输速度导致如果两者直接相连,cpu的性能要被浪费一部分,因此在cpu和内存之间会有一系列的缓存cache。缓存这东西有利有弊,利就是速度快,省时省力,弊就是当原始数据改变时,如果不采取相关措施,会造成缓存中存了个假数据,在线程并发时这种情况更常见,这个问题就是常说缓存不一致性的问题,很难受,需要想办法解决。怎么解决呢?引入一个协议吧,就是一组规定,让计算机听从这些规定,避免造成不一致的情况。
在缓存一致性协议中最为出名的是Intel的 MESI 协议,MESI协议保证了每一个缓存中使用的共享变量副本都是一致的,它的大致思想是,当CPU在操作Cache中的数据时,如果发现该变量是一个共享变量,也就是说在其他的CPU Cache中也存在一个副本,那么进行如下操作:
1)读取操作,不做任何处理,只是将Cache中的数据读取到寄存器。
2)写入操作,发出信号通知其他CPU将该变量的Cache line置为无效状态,其他CPU在进行该变量读取的时候不得不到主内存中再次获取。
在JVM中如果不做相关的规定,也会出现如此的情况,毕竟jvm中也有类似的缓存结构存在,存在缓存,存在并发,就存在缓存不一致性的问题,那么就需要引入一些列规定去约束Java虚拟机的运行,而这一系列的规则就是JMM,即Java内存模型。
在JMM的规范《JSR-133: Java Memory Model and Thread Specification》第14页The Java Memory Model中是这么介绍Java内存模型的:
A memory model describes, given a program and an execution trace of that program, whether the execution trace is a legal execution of the program. Java’s memory model works by examining each read in an execution trace and checking that the write observed by that read is valid.
A high level, informal overview of the memory model shows it to be a set of rules for when writes by one thread are visible to another thread. Informally, a read r can see the value of any write w such that w does not occur after r and w is not seen to be overwritten by another write w' (from r’s perspective).
翻译如下:
内存模型描述了一个给定的程序和该程序的执行轨迹,并且判断该程序的执行轨迹是否符合规定。Java的内存模型通过检查执行跟踪中的每个读并检查该读观察到的写是否有效来工作。
内存模型的一个更具体的、非正式的概述说明如下:它是一组规则,用于一个线程的写入对另一个线程可见。非正式地,一个读的进程r可以看到任何写的进程w写的值,这样w不会出现在r之后,而且w不会被另一个写w’覆盖(从r的角度来看)。
---
不得不说规范中这段话写的挺抽象,哪怕举例子也举的很抽象,不过还是很容易的可以知道JMM本质上是一组规则,这组规则作用于JVM,用于解决并发情况下出现的一系列问题。因此JVM和JMM是什么关系呢?我想很容易回答了——JMM是JVM的众多规范中一个。