基础概念
● 程序:源文件(代码),一个由值0和1组成的位(又称为比特)序列(静态概念)。
● 进程:一个正在运行的程序的一种抽象(动态概念)。
● 线程:每个线程都运行在由多个执行单元组成的进程上下文中,并享受同样的代码和全局数据。
JVM内存布局
● 元数据区:类信息、常量、static、JIT (信息共享 OOM)
● Java堆区:实力对象、GC (信息共享、易OOM)
● JVMStack:Java在方法执行的内存区域(线程私有,SO)
● PC:Java线程的私有数据(线程私有,SO)
● Native method stack:本地方法栈,针对JVM来说。本地方法栈 “主内”,虚拟机栈 “主外”,本地方法栈为Native方法服务,线程开始调用本地方法时,会进入一个不再受JVM约束得世界。本地方法可以通过JNI(Java Native Interface)来访问虚拟机运行时的数据区。(线程私有,SO)
OOM:OutOfMemoryError:Metaspace、Java heap space
SO:StackOverflowError
Java内存模型
(一)Java Memory Model是一种规范,抽象的概念,并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段、静态字段和构成数组对象的元素)的访问方式
● 主内存:共享的信息
● 工作内存:私有信息,基本数据类型,直接分配到工作内存,引用的地址存放在工作内存,引用的对象存放在堆中
● 工作方式:
○ A 线程修改私有数据,直接在工作空间修改
○ B 线程修改共享数据,首先把数据复制到工作空间中去,在工作空间中修改,修改完成以后再刷新工作内存中的数据
例如内存中有 x = 1,现在线程A要进行 +1 操作,那么先从内存加载 x = 1,然后到自己拥有的工作空间加一, 此时,x = 2。而线程B此时读取到的是 内存中的 x = 1。就存在了CPU缓存的一致性问题:并发处理不同步
解决方案:
➔ 1,总线加锁(BUS),该方案的缺点:降低CPU的吞吐量
➔ 2,缓存上的一致性协议(MESI):当CPU在cache中操作数据时,如果该数据时共享变量,数据在cache读到寄存器中,进行新修改,并且更新内存数据。CACHE、LINE置无效,其他的CPU就从内存中读数据。
(二)Java内存模型与硬件处理器
一对一模型
(三)Java内存模型与硬件内存架构的关系
如下图,存在交叉:数据不一致
(四)JMM的必要性
规范内存数据和工作空间数据
JMM对并发编程特性的保证
并发编程的三个重要特性
- 原子性:不可分割
- 可见性:线程只能操作自己工作空间中的数据
- 有序性:程序中的顺序不一定是执行顺序(编译重排序、指令重排序)
JMM对三个特性的保证
- JMM与原子性
- x = 1 写 原子性 如果是是私有数据具有原子性,如果是共享数据没原子性(读写)
- y = x 没有原子性,把数据读到工作空间(原子性),把x的值写给y(原子性)
- i++ 没有原子性,读 i 到工作空间,+1,刷新结果到内存
- Z = z + 1 没有原子性,z读到工作空间+1刷新结果到内存
多个原子性的操作合并到一起没有原子性,保证 方式:Synchronized、JUC、Lock的lock
- JMM与可见性
Volatile:在JMM模型上实现MESI协议
Synchronized:加锁
JUC juc Lock的lock
- JMM与有序性
Volatile:
Synchronized:
as-if-seria
Happens-before原则:
● 程序次序原则:
● 锁定原则:后一次加锁必须等前一次解锁
● Volatile原则:霸道原则
● 传递原则:A--B--C A---C
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。