Java内存模型

Java内存模型(JMM)

  • Java内存模型本身是一种抽象的概念,并不真实存在
  • JMM用来屏蔽硬件和操作系统的内存访问差异
  • 它描述的是一组规则或规范
    通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式
  • Java内存模型中规定所有变量都存储在主内存
    主内存是共享内存区域,主要存储的是Java 实例对象,所有线程创建的实例对象都存放在主内存中

  • 线程对变量的操作必须在工作内存中进行
    首先要将变量从主内存拷贝的自己的工作内存空间,然后对变量进行操作,操作完成后再将变量写回主内存,不能直接操作主内存中的变量,工作内存中存储着主内存中的变量副本拷贝

  • 本地变量是基本数据类型将直接存储在工作内存的帧栈结构中
  • 本地变量是引用类型,那么该变量的引用会存储在功能内存的帧栈中,而对象实例将存储在主内存

  • 线程间的通信必须通过主内存来完成

Tips:

  • 如果局部变量是reference类型,它引用的对象是共享的。
  • JVM不会把整个对象都拷贝一次,只拷贝访问到的字段。
  • volatile变量依然有工作内存的拷贝

硬件内存架构

  • 在CPU内部有一组CPU寄存器,寄存器是CPU直接访问和处理的数据,是一个临时放数据的空间。
  • 在寄存器和主内存间添加了CPU缓存
  • 访问主存时,会先读取主存数据到CPU缓存再读取CPU缓存到寄存器,
  • 写数据到主存时,先刷新数据到CPU缓存,再刷新数据到主内存。

一对一的线程模型

  • 使用Java线程时,Java虚拟机内部是转而调用当前操作系统的内核线程来完成当前任务。
  • 程序一般不会直接去调用内核线程,取而代之的是一种轻量级的进程(Light Weight Process)
  • 每个轻量级进程都会映射到一个内核线程

内存间交互操作

定义数据如何从主存拷贝到工作内存,以及如何同步回主存。
JMM定义8种操作来完成。

lock/unlock 用于控制主存变量的被锁定解锁
read 把变量从主存传至工作内存
load 把read的变量放入 工作内存的变量副本中
use 把工作内存的变量传给执行引擎
assign 从执行引擎接受变量赋值给工作内存的变量
store 把工作内存的变量传至主存
write 把store的变量写入主存


volatile

  • volatile变量保证所有线程可见性
  • volatile变量禁止指令重排序

适用于:

  • 运算结果不依赖变量的当前值,如i = 0; i++不适用
  • 变量不需要其他变量参与

happens-before

在JMM中,如果一个操作的执行结果需要对另一个操作可见,那么这两个操作之间必须要存在happens-before关系,这个的两个操作既可以在同一个线程,也可以在不同的两个线程中。

1、程序顺序规则:一个线程中的每个操作,happens-before于该线程中任意的后续操作。
2、监视器锁规则:对一个锁的解锁操作,happens-before于随后对这个锁的加锁操作。
3、volatile域规则:对一个volatile域的写操作,happens-before于任意线程后续对这个volatile域的读。
4、传递性规则:如果 A happens-before B,且 B happens-before C,那么A happens-before C。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值