JMM
java内存模型
1.1 java内存模型的抽象结构
在Java中,所有实例域、静态域和数组元素都存储在堆内存中,堆内存在线程之间共享,局部变量,方法定义参数和异常处理器参数不会在线程之间共它们不会有内存可见性问题,也不受内存模型的影响。
Java线程之间的通信有Java内存模型(JMM)控制,JMM决定了一个线程对共享变量的写入何时对另一个线程可见。JMM的抽象示意图如下:
从上图来看,如果线程A与线程B之间要通信的话,必须要经历下面2个步骤。
1)线程A把本地内存A中更新过的共享变量刷新到主内存中去。
2)线程B到主内存中去读取线程A之前已更新过的共享变量。
本地内存A和本地内存B由主内存中共享变量x的副本。假设初始时,这3个内存中的x值都为0。线程A在执行时,把更新后的x值(假设值为1)临时存放在自己的本地内存A中。当线程A和线程B需要通信时,线程A首先会把自己本地内存中修改后的x值刷新到主内存中,此时主内存中的x值变为了1。随后,线程B到主内存中去读取线程A更新后的x值,此时线程B的本地内存的x值也变为了1。
从整体来看,这两个步骤实质上是线程A在向线程B发送消息,而且这个通信过程必须要
经过主内存。JMM通过控制主内存与每个线程的本地内存之间的交互,来为Java程序员提供
内存可见性保证。
1.2 jvm
jvm 内存区域如下图:
方法区:类信息、常量、static 、JIT (信息共享)
Java堆区:实例对象 GC (信息共享) (OOM)
VM stack:Java方法在运行的内存模型 (OOM)
PC:java线程的私有数据,这个数据就是执行下一条指令的地址
Native method stack: 与JVM的native
1.3硬件架构和JMM
1.3.1 架构图如下:
a)CPU缓存的一致性问题:并发处理的不同步
b)解决方案:
i.总线加锁() 降低CPU的吞吐量
ii.缓存上的一致性协议(MESI)
当CPU在CACHE中操作数据时,如果该数据是共享变量,数据在CACHE读到寄存器中,进行新修改,并更新内存数据
CaCHE LINE置无效,其他的CPU就从内存中读数据
1.3.2 Java线程与硬件处理器
1.3.3Java内存模型与硬件内存架构的关系
交叉:数据的不一致