JMM内存模型

JMM内存模型

since:2019年9月2日 9:11
auth: Hadi
update: 2021年5月16日 22:36
参考:
	https://blog.csdn.net/lxm55913153/article/details/79208126

JMM

Java内存模型 Java Memort Model 简称为JMM。
JMM定义了java虚拟机在内存中的工作方式,是一种逻辑性的结构。
JMM定义了多线程之间共享变量的可见性以及如果在需要的时候对共享变量进行同步。

JMM操作类型

JMM为了进行数据的共享,对变量的操作分为以下8类:

  • read
    从主内存中读取数据。
  • load
    将主内存中的数据写入工作内存中(某子线程)
  • use
    从工作内存中读取数据来计算
  • assign
    将计算好的值重新写入工作内存中
  • store
    将工作内存的数据写回主内存
  • write
    将store写入的变量赋值给主内存中的变量位置
  • lock
    将主内存变量进行加锁,标识该变量被线程独占状态
  • unlock
    将主内存变量进行解锁,解锁后其他线程可以锁定该变量

具体流程可以参考下面流程图:
在这里插入图片描述

PS:红色方框中的操作也是在主内存中的进行的。
主内存 main memory,本地内存 local memory
local memory并不真实存在,只是抽象概念,涵盖缓存,写缓冲区,寄存器以及其他硬件和编译器优化等。

竞争现象和总线加锁

竞争现象

如果多个线程共享了一个对象,且多个线程在同时修改这个对象,那么就会产生竞争的现象。如下图:
在这里插入图片描述

两个线程同时对一个变量进行++的操作,那么可能会导致取数时为1,写回主内存的时候都写为1,导致丢失一次add操作。

总线枷锁

对上述情况的发生,我们可以操作lock的操作,就是会导致性能太低,无法高效。

Cpu从主内存读取数据到高速缓存,会在总线对这个数据加锁,
这样其它Cpu没法去读或写这个数据,直到这个Cpu使用完数据放锁之后其它Cpu才能读取该数据

MESI缓存一致性协议

多个Cpu从主内存读取同一个数据到各自的高速缓存,当其中某个Cpu修改了缓存里的数据,该数据会马上同步回主内存,其它Cpu通过总线嗅探机制可以感知到数据的变化从而将自己缓存里的数据失效,并进行数据的重新read、load。

Volatile缓存可见性实现原理

底层实现主要是通过汇编lock前缀指令,它会锁定这块内存区域的缓存(缓存行锁定)并回写到主内存。
在IA-32架构软件开发者手册对lock指令的解释:

  • 会将当前处理器缓存行的数据立即写回到系统内存。
  • 这个写回内存的操作会引起在其他CPU里缓存了该内存地址的数据无效(MESI协议)
    在这里插入图片描述

Java程序汇编代码查看

-server -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=compileonly,*VolatileVisibilityTest,prepareData
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值