深入理解 JVM 内存模型

深入理解 JVM 内存模型

  • 原文地址:
  • 原文作者:
  • 本文永久链接:
特别说明

当前文章内容迁移中,如有问题,请提交 issues 谢谢 ~~

一. 定义

JMM 即 Java 内存模型,并不是实质上存在的,它是一个约定或者规范。对数据的处理,必须从主内存加载至线程工作内存中。
处理完毕后,需要将工作内存中的数据刷回至主内存。

JMM 处理的是共享数据的 原子性,有序性,可见性。

工作内存

对于一个实例对象中的成员方法而言,如果方法中包括本地变量是基本数据类型(boolean、type、short、char、int、long、float、double),将直接存储在工作内存的帧栈中,而对象实例将存储在主内存(共享数据区域,堆)中。但对于实例对象的成员变量,不管它是基本数据类型或者包装类型(Integer、Double等)还是引用类型,都会被存储到堆区。至于 static 变量以及类本身相关信息将会存储在主内存中。

数据同步的原子操作

lock(锁定):作用于主内存的变量,把一个变量标记为一个线程独占状态;
unlock(解锁):作用于主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定;
read(读取):作用于主内存的变量,把一个变量值从主内存传输到线程的工作内存中,以后随后的load工作使用;
load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量;
use(使用):作用于工作内存的变量,把工作内存中的一个变量值传递给执行引擎;
assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋给工作内存的变量;
store(存储):作用于工作内存的变量,把工作内存中的一个变量的值传送到主内存中,以便随后的write的操作;
wirte(写入):作用于工作内存的变量,它把store操作从工作内存中的一个变量值传送到主内存的变量中。
如果要把一个变量从主内存中复制到工作内存中,就需要按顺序地执行 read 和 load 操作;
如果把变量从工作内存中同步到主内存中,就需要按顺序地执行 store 和 write 操作。

同步规则分析

同步规则分析

不允许一个线程无原因地(没有发生任何 assign 操作)把数据从工作内存同步回主内存中;
一个新的变量只能在主内存中诞生,不允许在工作内存中直接使用一个未被初始化(load 或者 assign)的变量。即就是对一个变量实施 use 和 store 操作之前,必须先自行 assign 和 load 操作;
一个变量在同一时刻只允许一条线程对其进行 lock 操作,但 lock 操作可不被同一线程重复执行多次,多次执行 lock 后,只有执行相同次数 unlock 操作,变量才会被解锁。lock 和 unlock 必须成对出现;
如果对一个变量执行 lock 操作,将会清空工作内存中此变量的值,在执行引擎使用变量之前需要重新执行 load 或 assign 操作初始化变量的值;
如果一个变量事先没有被 lock 操作锁定,则不允许对它执行 unlock 操作;也不允许去 unlock 一个被其他线程锁定的变量;
对一个变量执行 unlock 操作之前,必须先把此变量同步到主内存中(执行store 和 write 操作)。

原子性

可见性

有序性

缓存一致性问题

指令重排序问题

为了保证 CPU 运算单元的利用率,CPU 会对指令进行乱序优化。处理器会将乱序执行的指令在计算后进行重组。保证该执行结果和顺序执行一直。如果 CUP 中存在一个指令的计算依赖另一个指令的计算,那么

参考文章
Prev:
深入理解垃圾回收器 G1
Next:
深入理解 JVM 内存结构
Contents of this article
Contents of this article