天天看点

java内存模型 JMM详解

什么是java内存模型 或者说JMM模型

  这个新手特别容易混淆,内存模型不是JVM内存模型!

  • JMM是一种抽象的概念,并不真实存在,是一组规范或者规则;关注的是多个线程对共享内存空间和线程私有工作空间的访问方式,围绕并发的原子性、有序性、可见性来展开的,想要了解JAVA的并发编程,就应该理解JMM。
  • JMM通过定义了对变量(包括实例成员、静态成员和组成数组对象的元素)的访问方式,在程序运行时,运行程序的是实体是线程,每个线程创建时候,虚拟机都会为每个线程分配一定的内存空间,每个线程的内存空间用来存储线程私有的数据。但是JMM中规定数据都是存储在共享的主内存空间,而且每个线程不能直接操作主内存的空间,只能访问主内存的空间,且每个线程可以操作自己的工作空间,所以每个线程将自己用到的数据从共享的主内存空间中拷贝一份到其工作空间,操作完之后回写到主内存空间。
  • 在JMM模型中,初步的划分了工作内存和主内存。并且明确了一件事,线程中的工作空间是私有的,线程之间不能访问对方的工作空间。主内存是存放的是共享内存,由线程共享。

最终的线程模型如下

java内存模型 JMM详解

 JMM 与 JVM的关系

  JMM是Java内存模型,既然是模型,JMM规范指导产出了JVM,JVM正是根据JMM在物理内存划分出的结果。Java内存模型的作用是规范内存数据和工作空间数据的交互 。

java内存模型 JMM详解

   1、MM中内存有共享的内存空间和线程私有的工作空间,JVM运行时数据区有  方法区、堆、本地方法栈、虚拟机栈、程序计数器

   2、JVM运行时数据区共享的内存空间有   方法区和堆,所以可以理解  JMM的共享内存区域包含了 方法区和栈。JMM的线程私有空间包含了  程序计数器、本地方法栈、虚拟机栈

 这里插一个问题,我记得阿里的面试官问过,你知道JVM内存模型吗?那你知道为什么这样划分吗?在这里我觉得 JMM就是JVM为什么这样划分的一个答案。

Java内存模型与硬件内存架构的关系

   因为JMM只是一种抽象的概念,是一组规则,并不实际存在,不管是工作内存的数据还是主内存的数据,对于计算机硬件来说都会存储在计算机主内存、CPU缓存和CPU寄存器中,所以Java内存模型和计算机硬件内存架构是一个相互交叉的关系,是一种抽象概念划分与真实物理硬件的交叉。

java内存模型 JMM详解

计算机硬件架构存在的问题:

多个CPU并行处理缓存数据时,并发处理的不同步,会产生数据一致性问题。

解决方案:

Ⅰ. 总线加锁:CPU核执行一个线程去访问数据做操作的时候,向总线上发送一个LOCK信号,通过把内存和CPU之间的通信锁住,把并行化的操作变成了串行。虽然能解决一致性问题,但是会导致很严重的性能问题。

Ⅱ. 缓存的一致性协议(MESI):当CPU在Cache中操作数据时,如果该数据是共享变量,数据在Cache读到寄存器中,进行新修改,并更新内存数据Cache Line置无效。其他的CPU拿取数据,若Cache Line为无效会从内存中拿取。

JAVA内存模型数据同步8大原子操作 

1、8大原子操作:

     lock(锁定):把一个变量标记为一条线程独占状态

     unlock(解锁):把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定

     read(读取):把主内存中的一个变量读取传输到线程的工作内存,以便随后load动作使用

     load(加载):把read到线程工作内存的变量放入工作内存的变量副本中

     use(使用):把线程工作内存中的一个变量值传递给执行引擎

     assign(赋值):从执行引擎接收到的新值赋值给变量。返给工作内存

     store(存储):把线程工作内存的一个变量值传递给主内存,以便后面的write使用

     write(写入):把store到主内存的变量值赋值给变量