摘要
之前我们讲解过cpu多级缓存模型,但是对于JVM来说为了屏蔽掉各种操作系统跟各种硬件的差异,是各个操作系统和硬件数据读写原理一致性而引入了java内存模型JMM;
思维导图
本章节内容如下:
内容
JMM模型前言: JMM它是一个虚拟的东西,是一个抽象的概念;描述的是一组规范;抽象的就是cpu的多核缓存架构;为了实现java跨平台;屏蔽掉计算机硬件跟操作系统,保证在各个操作系统上读取数据的一致性。如下,我们可以把java内存模型跟计算机多核cpu缓存模型进行抽象。
java的工作内存可以是:计算机主内存、cpu的多级缓存、cpu的寄存器。jvm里面的主内存可以是:计算机主内存、cpu的多级缓存、cpu的寄存器。
JMM模型:
Java Memory Model简称JMM。
JMM与JVM内存区域的划分是不同的概念层次,更恰当说JMM描述的是一组规则,通过这组规则控制程序中各个变量在共享数据区域和私有数据区域的访问当时,JVMM是围绕原子性、有序性、可见性展开。
JVM运行时数据区跟JMM区别:
1、两者之间是两个完全不同的概念。JMM是一个抽象的虚拟的抽象规则; 而JVM内存模型是真是存在的。JVM是我们运行时数据去的内存划分,里面的内存都是真是存在的。JMM是一组规则。
2、但是他们也有相同地方:我们JMM有私有内存:工作内存 和共有内存:主内存的划分;我们的JVM也是有线程私有的内存:程序计数器、本地方法栈、java虚拟机栈; 线程共有的:java堆、方法区划分。
JVM虚拟机规范主内存与工作内存:
假如我们有一个实例对象:这个实例对象有成员方法跟成员变量;对这个对象实例的成员方法来说;如果方法里面使用的变量是基本类型的话,其数据是存在到我们的Java虚拟机栈的,如果方法里面的变量是引用类型的话,其对应的数据是存放到主内存里面的Java虚拟机堆的,方法区栈帧值存放对应变量引用地址:reference。
上面是对成员方法来说的;对于成员变量来说:不管是基本类型还是引用类型。都会被存放到堆区。主内存里面的实例对象是可以共享的。
Java内存模型与硬件内存架构的关系:
JMM模型跟CPU缓存结构类似,JMM是基于CPU缓存模型建立起来的,JMM模型是标准化的,屏蔽掉了底层不同计算机区别。对于硬件内存来说只有寄存器、缓存内存、主内存的概念。并没有工作内存(线程私有数据区域)和主内存(堆内存)之分,也就是说Java内存模型对内存的划分对硬件内存并没有任何影响。
对于我们硬件内存架构来说,其只有cpu寄存器、cpu多级缓存模型、主内存之分;没有工作内存说法。JMM只是一个抽象的概念;JMM所对应的工作内存、主内存是交叉对应与CPU的寄存器、CPU多级缓存、主内存(RAM)。
JMM与硬件内存架构关系就是: 概念实际物理概念的对比。
JMM存在的必要性:
由于JVM运行程序的实体是线程:
由于JVM运行实体是线程,JVM会为每一个线程创建一个工作内存,有些地方叫做JVM运行时栈空间。用于存储我们JVM的私有数据。线程与主内存中的变量操作必须通过工作内存间接完成。主要过程是将变量从主内存拷贝到每个线程各自的工作内存空间,然后对变量进行操作,操作完成后再将变量写回主内存,如果存在两个线程同时对一个主内存中实例对象的变量进行操作就有可能诱发线程安全问题。
我们Java内存模型规定,我们所有的变量实例都是存储在主内存里面。主内存是共享的区域,所有的线程都可以共享去访问。但是线程对变量的操作又必须是在工作内存里面的。所以首先从主内存里面复制变量实例到线程工作内存,然后操作之后,将数据写入到主内存。线程之间是不能访问对方的工作内存数据的。那么线程之间又是怎样通信的呢?线程之间通信是通过I/O总线来读写主内存来通信的。