
1 Java内存模型(JMM)的意义
内存模型描述程序的可能行为。
Java虚拟机规范中试图定义一种Java内存模型
来屏蔽掉各种硬件和操作系统的内存访问差异
,规定
- 线程如何,何时能看到其他线程修改过的共享变量的值
- 在必要时如何同步地访问共享变量
以实现让Java程序在各种平台下都能达到一致性的内存访问效果。
Java编程语言内存模型 通过检查执行跟踪中的每个读操作,并根据某些规则检查该读操作观察到的写操作是否有效来工作。
只要程序的所有执行产生的结果都可以由内存模型预测。具体的实现者任意实现,包括操作的重新排序和删除不必要的同步。
内存模型决定了在程序的每个点上可以读取什么值
1.1 Shared Variables 共享变量的描述
可以在线程之间共享的内存称为
共享内存或堆内存
所有实例字段、静态字段和数组元素都存储在堆内存中
如果至少有一个访问是写的,那么对同一个变量的两次访问(读或写)是冲突的。
https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4.12 主内存与工作内存
- 工作内存缓存
-
Java内存模型深入详解(JMM)(上)1 Java内存模型(JMM)的意义2 主内存与工作内存 - Java内存模型的主要目标是定义
即在虚拟机中将变量存储到内存和从内存中取出变量值这样的底层细节各个变量的访问规则
- 此处的变量包括了实例域,静态域和构成数组对象的元素,但不包括局部变量与方法参数,因为后者是线程私有的,不存在竞争
为了获得比较好的执行效率,JMM并没有限制执行引擎使用处理器的特定寄存器或缓存来和主内存进行交互,也没有限制即时编译器调整代码执行顺序这类权限。
JMM规定
所有的变量都存储在主内存(Main Memory)
每条线程有自己的工作内存(Working Memory)
保存了该线程使用到的变量的主内存副本拷贝(线程所访问对象的引用或者对象中某个在线程访问到的字段,不会是整个对象的拷贝!)
线程对变量的所有操作(读,赋值等)都必须在工作内存中进行,不能直接读写主内存中的变量
volatile变量依然有工作内存的拷贝,只是他特殊的操作顺序性规定,看起来如同直接在主内存读写
不同线程之间无法直接访问对方工作内存中的变量,线程间变量值的传递均要通过主内存
JVM模型与JMM不是同一层次的内存划分,基本是没有关系的,硬要对应起来,从变量,内存,工作内存的定义来看
- 主内存 === Java堆中的对象实例数据部分
- 工作内存 === 虚拟机栈中的部分区域
- 从更底层的层次来说
- 主内存直接对应于物理硬件的内存
- 为了更好的运行速度,虚拟机(甚至硬件系统的本身的优化措施)可能会让工作内存优先存储于寄存器和高速缓存器中,因为程序运行时主要访问读写的是工作内存