Java内存模型的深层理论

简介:  Java 内存模型 , 即 Java Memory Model JMM 来屏蔽各种硬件和操作系统的内存访问差异,以实现让Java 在各种平台都达到一致的访问效果.Java 内存模型规范了 JVM 如何 禁用缓存 和 编译优化 的方法.

1681518316904.png

本文部分内容选自<<深入理解Java虚拟机>> 以及 CrazyDailyQuestion的ArtarisCN

引言

  Java 内存模型 , 即 Java Memory Model,JMM 来屏蔽各种硬件和操作系统的内存访问差异,以实现让Java 在各种平台都达到一致的访问效果.Java 内存模型规范了 JVM 如何 禁用缓存编译优化 的方法.


一.Main Memory和Working Memory

  • Java 规定所有的变量都存储在主内存(Main Memory)中
  • 每条线程Working Memory 保存了该Thread使用的变量的Main Memory副本copy
  • Thread间变量值通过 Main Memory 传递
  • Thread对变量操作(赋值,读取)只能在 Working Memory 进行, Main Memory 不可读
  • ThreadA   无法 直接 访问 ThreadB  Working Memory 变量,同理ThreadB也是如此

下面我就用图文并茂的方式给大家展示一下: Thread,Main Memory和Working Memory的交互关系

1681518428563.png

二.内存间交互操作

那么,变量是如何通过Main Memory copy给  Working Memory,如何从 Work Memory sync 到 Main Memory的呢?

jvm实现必须保证每一种操作都是原子的,不可细分的(double 和 long比较特殊)

Java 提出了 8种操作类型


变量作用域: Main Memory


方法 作用
lock(🔒) 把Thread 设置线程独有 Tag
unlock(🔓) 释放变量,给其他Thread使用
read(读取) 变量从Main Memory传输到Thread 的 Working Memory途径


变量作用域: Working Memory


方法 作用
load(载入) 变量值放到Working Memory 的变量副本中
use(使用) Working Memory的变量值传给执行引擎,JVM收到需要执行的变量的字节码指令时候,会执行这个操作
assign(赋值) 他把一个从执行引擎接收的值赋给Working Memory 的变量,JVM收到需要执行的变量的字节码指令时候,会执行这个操作
store(存储) 把变量值传给 Main Memory

变量作用域: Main Memory

方法 作用
write(写入) Working Memory的变量放到Main Memory中

 1681518591003.png

操作规则:

  太官方,主要是为了解决Java并发安全,Android用的不太多,只想理清流程,不想看细节~

三.volatile

  没有被volatile位数据可以分割为两个32位进行操作,volatile和syhnronized功能类似,解决多Thread竞争问题

操作规则:

  • 保证变量对多有Thread的可见性
  • 变量值被修改,Thread能立即感知这个值
  • 在切换线程时候,变量可能被重定义,却来不及更新建议用 volatile,但是 volatile 并不能完美解决线程安全问题,只能做变量提前预判,此时得采用acomic或者syhnronized等其他方式


四.long和double

  long 和 double 具有非原子性,不需要用考虑使用volatile修饰


五.原子性,可见性,有序性


  • 原子性: 除了 long 和 double以外的基本数据类型都具有原子性

  • 可见性: 当一个线程修改了这个值,其他线程能够立即感知,即 Main Memory 传递的方式具有可见性
  • volatile 能保证新值能立即同步到 Main Memory,以及每次使用 从 Main Memory 立即 refresh.
  • final 字段在constrctor方法 init 后,constrctor 没有把 "this" 引用传递出去(this 逃逸非常危险),那么在其他线程中就能看见 final 字段的值
  • synchronized 变量在同步代码块,unlock之后,必须回到 Main Memory,执行完write操作

  • 有序性:
  • 本线程中所有操作都是有序的(Whithin-thread As-if-Serial Semantics)
  • ThreadA watch ThreadB 都是无序的(指令重排,Main Memory与Working Memory 同步 延迟)
  • volatile 禁止指令重排
  • synchronized 一个变量 一个时刻只允许一条线程进行lock

六.happen-before

  • 程序次序规则
      在一个程序里面,按照程序代码顺序,书写在前面的操作happen-before发生书写在后面的操作

  • 管程锁定规则
      同一把锁,unlock happen-before lock 操作

  • 线程中断原则

  Thread.intercupt()方法检测到是否中断发生


  • 传递性

  Happens-Before 具有传递性,如果 A Happens-Before B,B Happens-Before C,则 A Happens-Before C


  • 对象终结规则

  对象 init happen-before finalize()


七.问题导致原因

  • 缓存导致的可见性问题
  • 切换线程导致的原子性问题
  • 编译优化带来的有序性问题「指令重排」
相关文章
|
2月前
|
安全 Java 应用服务中间件
Spring Boot + Java 21:内存减少 60%,启动速度提高 30% — 零代码
通过调整三个JVM和Spring Boot配置开关,无需重写代码即可显著优化Java应用性能:内存减少60%,启动速度提升30%。适用于所有在JVM上运行API的生产团队,低成本实现高效能。
230 3
|
3月前
|
存储 缓存 Java
Java数组全解析:一维、多维与内存模型
本文深入解析Java数组的内存布局与操作技巧,涵盖一维及多维数组的声明、初始化、内存模型,以及数组常见陷阱和性能优化。通过图文结合的方式帮助开发者彻底理解数组本质,并提供Arrays工具类的实用方法与面试高频问题解析,助你掌握数组核心知识,避免常见错误。
|
28天前
|
Java 大数据 Go
从混沌到秩序:Java共享内存模型如何通过显式约束驯服并发?
并发编程旨在混乱中建立秩序。本文对比Java共享内存模型与Golang消息传递模型,剖析显式同步与隐式因果的哲学差异,揭示happens-before等机制如何保障内存可见性与数据一致性,展现两大范式的深层分野。(238字)
49 4
|
1月前
|
存储 缓存 Java
【深入浅出】揭秘Java内存模型(JMM):并发编程的基石
本文深入解析Java内存模型(JMM),揭示synchronized与volatile的底层原理,剖析主内存与工作内存、可见性、有序性等核心概念,助你理解并发编程三大难题及Happens-Before、内存屏障等解决方案,掌握多线程编程基石。
|
2月前
|
缓存 监控 Kubernetes
Java虚拟机内存溢出(Java Heap Space)问题处理方案
综上所述, 解决Java Heap Space溢出需从多角度综合施策; 包括但不限于配置调整、代码审查与优化以及系统设计层面改进; 同样也不能忽视运行期监控与预警设置之重要性; 及早发现潜在风险点并采取相应补救手段至关重要.
468 17
|
6月前
|
存储 缓存 Java
【高薪程序员必看】万字长文拆解Java并发编程!(5):深入理解JMM:Java内存模型的三大特性与volatile底层原理
JMM,Java Memory Model,Java内存模型,定义了主内存,工作内存,确保Java在不同平台上的正确运行主内存Main Memory:所有线程共享的内存区域,所有的变量都存储在主存中工作内存Working Memory:每个线程拥有自己的工作内存,用于保存变量的副本.线程执行过程中先将主内存中的变量读到工作内存中,对变量进行操作之后再将变量写入主内存,jvm概念说明主内存所有线程共享的内存区域,存储原始变量(堆内存中的对象实例和静态变量)工作内存。
222 0
|
3月前
|
监控 Kubernetes Java
最新技术栈驱动的 Java 绿色计算与性能优化实操指南涵盖内存优化与能效提升实战技巧
本文介绍了基于Java 24+技术栈的绿色计算与性能优化实操指南。主要内容包括:1)JVM调优,如分代ZGC配置和结构化并发优化;2)代码级优化,包括向量API加速数据处理和零拷贝I/O;3)容器化环境优化,如K8s资源匹配和节能模式配置;4)监控分析工具使用。通过实践表明,这些优化能显著提升性能(响应时间降低40-60%)同时降低资源消耗(内存减少30-50%,CPU降低20-40%)和能耗(服务器功耗减少15-35%)。建议采用渐进式优化策略。
178 1
|
3月前
|
存储 监控 算法
Java垃圾回收机制(GC)与内存模型
本文主要讲述JVM的内存模型和基本调优机制。
|
4月前
|
SQL 缓存 安全
深度理解 Java 内存模型:从并发基石到实践应用
本文深入解析 Java 内存模型(JMM),涵盖其在并发编程中的核心作用与实践应用。内容包括 JMM 解决的可见性、原子性和有序性问题,线程与内存的交互机制,volatile、synchronized 和 happens-before 等关键机制的使用,以及在单例模式、线程通信等场景中的实战案例。同时,还介绍了常见并发 Bug 的排查与解决方案,帮助开发者写出高效、线程安全的 Java 程序。
224 0