java内存模型JMM

基本概念

程序:代码,完成某一件任务,代码序列(静态的概念)
进程:程序在某些数据上的一次运行(动态的概念)
线程:一个进程可能包含一个或多个线程(占有资源的独立单元)

JVM与线程

JVM是在类被调用的时候才会被启动。先有JVM线程,然后才其他(main)线程(JVM创建了其他线程,)。

JVM 内存区域


信息共享

方法区:类信息(由类加载器加载)、常量、static、JIT (动态编译的代码)。(反射操作的地方)。
Java堆区:实例对象 GC工作主要区域 (OOM)。
数据不共享
VM stack(虚拟机栈):Java方法在运行的内存模型 (OOM)
如果虚拟机栈内存溢出指的是整体内存不足,不是单个栈帧内存不足,栈帧的内存是有大有小的。

PC(程序计数器):java线程的私有数据,这个数据就是执行下一条指令的地址
Native method stack: JVM的本地方法

java内存模型 Java memory model(JMM,抽象的概念)

主内存:共享的信息
工作内存:私有信息,基本数据类型,直接分配到工作内存,引用的地址存放在工作内存,引用的对象存放在堆中
工作方式:
A 线程修改私有数据,直接在工作空间修改
B 线程修改共享数据,把数据复制到工作空间中去,在工作空间中修改,修改完成以后,刷新内存中的数据

JMM三个特征

原子性:不可分割 (类似与银行转账,必须要一个加钱一个减钱)
A) X=10 单纯的写是有原子性。如果是私有数据具有原子性,如果是共享数据没原子性(读写)

B) Y=x 没有原子性

a) 把数据X读到工作空间(原子性)

b) 把X的值写到Y(原子性)

C) I++ 没有原子性

a) 读i到工作空间

b) +1;

c) 刷新结果到内存

D) Z=z+1 没有原子性

a) 读z到工作空间

b) +1;

c) 刷新结果到内存

多个原子性的操作合并到一起没有原子性

保证方式:

Synchronized

JUC Lock的lock

可见性:线程只能操作自己工作空间中的数据

加锁:Synchronized、Lock

关键字:Volatile:在JMM模型上实现MESI协议

有序性:程序中的顺序不一定就是执行的顺序。

(编译重排序(编译优化)、指令重排序(指令优化),为了优化代码提高效率)

as-if-aeria原则:

单线程中重排后不影响执行的结果。

Happens-before原则:

  1. 程序次序规则:在-一个线程内,按照程序代码顺序,书写在前面的操作先行发生于书写在后面的操作。准确地说,应该是控制流顺序而不是程序代码顺序,因为要考虑分支。循环等结构。

  2. 管程锁定规则:一个unlock操作先行发生于后面对同一个锁的lock操作。 这里必须强调的是同一个锁,而“后面"是指时间上的先后顺序。

  3. volatile变量规则:对一个volatile变 量的写操作先行发生于后面对这个变量的读操作,这里的"后面"同样是指时间上的先后顺序。

  4. 线程启动规则: Thread对象的start()方法先行发生于此线程的每-一个动作。

  5. 线程终止规则:线程中的所有操作都先行发生于对此线程的终止检测,我们可以通过Thread,join () 方法结束、Thread.isAlive ()的返回值等手段检测到线程已经终止执行。

  6. 线程中断规则:对线程interrupt()方 法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过Thread.interrupted()方法检测到是否有中断发生。

  7. 对象终结规则: -个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法的开始。

Happens-Before的1个特性:传递性。A--B--C A--C A在B前,B在C前。可以得到A的语句必须要在C语句前面执行。

Java内存模型涉及的几个关键词:锁、volatile字段、 final修 饰符与对象的安全发布。

  1. 锁操作是具备happens- before关系的,解锁操作happens-before之后对同一把锁的加锁操作。实际上,在解锁的时候,JVM需要强制刷新缓存,使得当前线程所修改的内存对其他线程可见。

  2. volatile字段可以看 成是一-种不保证原子性的同步但保证可见性的特性,其性能往往是优于锁操作的。但是,频繁地访问volatile字段也会出现因为不断地强制刷新缓存而影响程序的性能的问题。

  3. final修饰的实例字段则是涉及到新建对象的发布问题。当一个对象包含final修饰的实例字段时,其他线程能够看到已经初始化的final实例字段,这是安全的。

Java内存模型底层怎么实现的

主要是通过内存屏障(memory barrier)禁止重排序的,即时编译器根据具体的底层体系架构,将这些内存屏障替换成具体的CPU指令。对于编译器而言,内存屏障将限制它所能做的重排序优化。而对于处理器而言,内存屏障将会导致缓存的刷新操作。比如,对于volatile,编译器将在volatile字段的读写操作前后各插入一些内存屏障。

posted @ 2020-04-07 21:55  无话可说丶  阅读(207)  评论(0编辑  收藏  举报