JVM——Java内存模型

处理器、高速缓存和主内存关系

在这里插入图片描述
在多处理器系统中,每个处理器都有自己的高速缓存,而他们又共享同一主内存。当多个处理器的运算任务都涉及同一主内存区域时,将可能导致各自的缓存数据不一致,为了解决一致性的问题,需要各个处理器访问缓存时都遵循一些协议,在读写时要根据协议来进行操作,这类协议有MSI、MESI、MOSI、Synapse、FireFly及Dragon Protocol等

内存模型

内存模型是指,在特定的操作协议下,对特定的内存或者高速缓存进行读写访问的抽象过程。不同架构的物理机器可以拥有不一样的内存模型

Java内存模型(JMM)

通过定义一种Java内存模型来屏蔽各种硬件和操作系统的内存访问差异,使得Java程序在各平台达到一直的内存访问效果。
JMM的主要目的是定义程序中各个变量(实例字段、静态字段和构成数组对象的元素,不包括局部变量和方法参数)的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节

线程、主内存和工作内存关系

在这里插入图片描述
JMM规定所有的变量都存储在主存中,每个线程有自己的工作内存,线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝
线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存的变量,不同的工作线程之间也无法访问对方工作内存中的变量
JMM和Java内存区域并没有关系,如果一定要勉强对应起来
主内存-------->Java堆中对象实例的数据部分--------->物理机的内存
工作内存--------->虚拟机栈中部分区域-------->优先使用寄存器和高速缓存

内存间交互操作

JMM定义了8种操作来完成主内存和工作内存之间具体的交互协议,每一种操作都是原子的、不可再分的

  1. lock:作用于主内存变量,把一个变量标识为一个线程独占的状态;
  2. unlock:作用于主内存变量,把一个锁定的变量释放,释放后的才可以被其他线程使用;
  3. read:作用于主内存变量,把变量的值从主内存传输到线程的工作内存中;
  4. load:作用于工作内存变量,把从主内存传输的变量值放入工作内存的变量副本中;
  5. use:作用于工作内存变量,把工作内存中的变量的值传递给执行引擎,每当虚拟机遇到需要使用变量值的字节码指令时执行;
  6. assign:作用于工作内存变量,将执行引擎的收到的值赋给工作内存的变量,遇到赋值字节码指令执行;
  7. store:作用于工作内存变量,把工作内存中的变量值传输给主内存;
  8. write:作用于主内存变量,从工作内存中得到的值放入主内存的变量中;

指令重排序

为了使得处理器内部的运算单元能尽量被充分利用,除了增加告诉缓存以外,处理器可能会对输入的代码进行乱序执行优化,只要程序的最终结果与它顺序化情况的结果相等,那么指令的执行顺序可以与代码逻辑顺序不一致,这个过程就叫做指令的重排序。
目的是使指令更加符合CPU的执行特性,最大限度的发挥机器的性能,提高程序的执行效率。

volatile型变量特殊规则

当一个变量被定义为volatile之后,它具备两个特点,一是保证此变量对所有线程的可见性,即当一个线程修改了这个变量值后,新的值对其他线程来说是立即可见的,普通变量在线程间传递需要通过主内存来完成。
volatile变量在各个线程的工作内存中不存在一致性问题,在各个工作线程中volatile变量可以存在不一致的情况,但由于每次使用之前都要先刷新,执行引擎看不到不一致的情况,因此可以任务不存在一致性问题,但是Java里面的运算并非原子操作,导致volatile变量在并发下一样是不安全的,例子如下:
在这里插入图片描述
运行结果每次都不一样,但是结果并非是期望的100000
在这里插入图片描述 在这里插入图片描述
出现上述问题的原因是在自增运算inc++中,我们首先查看代码编译后的字节码,虽然一行字节码指令并不意味着一个原子操作
在这里插入图片描述
inc++这一行代码被编译为4行字节码指令
getstatic 指令将inc的值取到操作栈顶,volatile保证了此时inc的值是正确的
iconst_1、iadd执行时,其他线程可能已经把inc的值增加,而在操作栈顶的值就变成了过期数据,
所以在putstatic指令执行后就可能把较小的inc值同步回主内存中
由于volatile变量只能保证可见性,所以不符合以下两种规则仍然需要使用synchronized和原子类:

  1. 运算结果不依赖变量的当前值,或者确保只有单一的线程修改变量的值;
  2. 变量不需要与其他的状态变量共同参与不变约束

利用volatile修饰的变量第二个特点是禁止指令重排序优化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值