jvm 内存模型介绍
物理机中的内存模型介绍:
处理器a –》 高速缓存 –》 缓存一致性协议 –》主内存
处理器b –》高速缓存 –》 缓存一致性协议 –》 主内存
计算机的存储设备和处理器的运算速度有几个数量级的差距,因此现代计算机系统不能不加入一层读写速度尽可能接近处理器运算速度的高速缓存Cache来作为内存和处理器之间的缓冲:将运算需要的数据复制到Cache中,来让运算能>加速进行,当运算结束,再从Cache中同步回内存中。这样处理器无需等待缓慢的内存读写了。
基于高速缓存的存储交互很好的解决了处理器和内存的矛盾问题,但也为计算机系统带来了更高的复杂度,缓存一致性问题(Cache Coherence ),当多个处理器的运算任务涉及同一块主内存时,将导致各自的缓存数据不一致,在处理一致性问题时,需要各个处理器访问Cache时遵循一些协议如MSI、MESI(IIIinois Protocol)、MOSI、Synapse、
Firefly、Dragon Protocol等。
同时除了增加高速缓存之外,处理器可能会对输入代码进行乱序执行,即所谓的指令重排序(Out Of Order Execution)优化,处理器会在计算之后将乱序执行的结果重组,保证该结果与顺序执行的结果一致。但并不保证各个语句计算的顺序与输入代码的顺序一致。当然jvm也有类似的内存模型以及指令重排序优化。
主流程序语言诸如C等直接实用物理硬件和操作系统的内存模型,java虚拟机也正是基于物理硬件的操作系统定义和完善自己的内存模型。
java内存模型的主要目标是定义程序中各个变量的访问规则,即虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。
当然此处的变量包含实例字段,静态字段和构成数组对象的元素,对于线程私有的变量,不会被共享,自然也就不存在竞争问题。
主内存和工作内存:java内存模型中规定所有的变量都存储在主内存中,可以类比物理硬件的内存,但是此处是虚拟机内存的一部分,每一条线程还有自己的工作内存,可以类比处理器高速缓存,线程的工作内存中保存了被该线程使用的变量的主内存副本,线程对变量的所有操作都必须在工作内存中进行。而不能直接读写主内存的变量,不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量的传值需要通过主内存来完成
java线程 <—- 工作内存 —-> sava和load操作 主内存
内存间交互操作:
关于主内存和工作内存之间具体的交互协议,即一个变量从主内存copy到工作内存,如何在工作内存同步回主内存之间的实现细节由java内存模型中8种操作来完成,如下的每一种操作都是原子性不可再分的。