简介
JMM是一种规范,它规范了Java虚拟机与计算机内存是如何工作的。它规定了一个线程,如何或者何时可以看到其他线程修改过的变量的值,以及在必须时如何同步的访问变量。
堆
运行时的数据区,堆是由垃圾回收来负责的。堆的优势是可以动态的分配内存大小。生存期也不必事先告诉编译器,因为是在运行时动态分配的内存。因为是运行时动态分配内存,所以,内存的读取效率还是比较低的。
栈
栈的优势是比堆的存取速度要快。仅次于计算机中的寄存器。缺点是,存在于栈中的数据的大小和生命周期必须是确定的。缺乏灵活性。栈中存放一些基本类型的数据变量。比如int short float 等。
同步操作与规则
LOCK
作用于主内存的变量,把一个变量标示为一个线程独占的状态。
UNLOCK
作用于主内存的变量。作用于一个锁定的变量,释放后的变量才能被其他的线程锁定。
READ
将变量的值从主内存载入到工作内存当中。
LOAD
作用于工作内存的变量,把 read 读取到的主内存的变量副本放入到工作内存当中。
USE
将工作内存中的一个变量传递给工作引擎。每当虚拟机需要一个指令的字节码指令时,use指令就会执行。
ASSIGN
把从执行引擎接收到的值复制给工作变量。每当虚拟机遇到一个给变量赋值的字节码指令时,虚拟机会执行 assign 操作
Store
把工作内存中的变量传递到主内存中。以便随后的 write 操作能够使用。
Write
作用于主内存,将Store得到的工作内存的变量赋值到主内存当中。
操作执行规则
- read 和 load 、Store 和 Write可以不是连续执行。
- 一个线程不允许丢弃其最近的assign操作。
- 不允许一个线程在没有 assgin 操作的情况下将工作内存中的数据写回到主内存。
- 一个新的变量只能诞生在主内存当中。不允许在工作内存当中使用一个未被初始化(read->load 或者 assign)的变量。
- 一个变量同一个时间只允许一个线程对其进行lock操作。
- 一条线程可以对一个变量执行多次lock操作,需要执行同样次数的unlock操作才能对其进行解锁。
- 如果一个变量执行了lock操作,将会清空工作变量中此变量的值,在执行引擎使用这个变量之前,需要重新 read -> load 或者assign操作。
- 如果一个变量没有执行 lock 操作,是不允许对其进行 unlock 操作,也不允许 unlock 一个被其他线程 lock 的变量。
- 对于一个变量在 unlock 之前必须把工作内存的值同步回主内存当中,也就是执行 Write 和 Store 操作。
其他
一些用 final 修饰过的值是不允许其他线程对其修改的。
网友评论