方法区[线程共享区域]
读取加载.class (字节码)
class文件分析
将源码转换为指令 new
堆
保存创建的的对象
- 对象头
- 数据体
根据垃圾回收的需要分代回收
划分区域
程序计数器[线程各自独享]
虚拟机栈[不同线程各自独享]
方法集合 告诉线程要去执行哪个方法
本地方法栈
JVM内存模型
基本概念
程序 : 完成某一任务的代码序列(静态的概念)
进程 : 程序在某些数据上的一次运行(动态的概念)
线程 : 一个进程可能包含一个或者多个线程(占有资源的独立单元)
JVM
-
JVM什么时候启动 ?
类被调用 JVM线程 >> 其他的线程
-
JVM内存区域
方法区 : 类信息 ,常量,static,JIT
堆区 : 实例对象 [GC] (OOM)
方法区与堆区可以进行信息共享
VM static : Java方法在运行时的内存模型
-
栈帧 : 每个方法存在一个栈帧 [方法私有]
-
存放在栈帧的东西 : 局部变量 引用类型数据的地址 操作数栈
Native method stack : 与JVM的native有关 线程私有
3. Java 内存模型 Java memory model JMM (规范 抽象的模型)
-
主内存 : 共享的信息
-
工作内存 : 私有信息
- 基本数据类型 ,直接分配到工作空间
- 引用对象地址存放在工作空间,引用的对象存放在堆中
-
工作方式:
A 线程修改私有数据 ,直接在工作空间修改
B 线程修改共享数据 ,把数据复制到工作空间 ,然后在工作空间中修改 ,修改完成以后,刷新内存中的数据.
-
硬件内存架构与Java内存模型
CPU 缓存一致性问题 : 并发处理的不同步
解决方案 :
i . 总线加锁 (BUS) : 封锁粒度大,降低CPU的吞度量
ii. 缓存一致性的协议(MESI) :
当CPU在Cache中操作数据时,如果该数据是共享变量, 数据在Cache读到寄存器中
进行修改,并更新内存数据,Cache LINE 置无效 ,其他的CPU就直接从内存中读数据
(1) Java内存模型与硬件内存架构的关系.
交叉 : 数据的不一致
(2) Java线程和硬件处理器
(4) Java内存模型的必要性
java内存模型作用 : 规范内存数据和工作空间数据的交互
-
并发编程的三个重要特征
原子性 : 不可分割 [转账性]
可见性 : 线程只能操作自己工作空间的数据
有序性 : 程序中的数据不一定就是执行的顺序
- 编译重排序 提高效率
- 指令重排序
as-if-seria : 单线程中重排后不影响执行的结果
happens-before :
为什么进行重排序?
CPU执行将执行时间少的指令排在前面,加快指令流水线
- JMM对三个特征的保证
(1) JMM与原子性
A) X = 10 写 原子性 如果是私有数据具有原子性,如果是共享数据没有原子性
B) Y = x 没有原子性
- 把数据x读到工作空间(原子性)
- 把x的值写到Y(原子性)
C) i++
- 读i到工作空间
- +1
- 刷新结果到内存
多个原子性操作合并到一起没有原子性,
保证方式 :
Synchronized
JUC Lock的lock
(2) JMM与可见性
Volatile :在JMM模型上实现MESI
Synchronized :加锁
JUC Lock的lock
(3)有序性
Volatile :
Synchronized :
Happens-before原则 :
-
程序次序原则
-
锁定原则 : 后一次加锁必须等前一次解锁
-
Volatile 原则 : 霸道原则
-
传递原则 : A —B---C
总结:
JVM 内存区域和JMM的关系JVM 是基于JMM模型进行划分的