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内存模型深度解析:从理论到实践####
【10月更文挑战第21天】 本文深入探讨了Java内存模型(JMM)的核心概念与底层机制,通过剖析其设计原理、内存可见性问题及其解决方案,结合具体代码示例,帮助读者构建对JMM的全面理解。不同于传统的摘要概述,我们将直接以故事化手法引入,让读者在轻松的情境中领略JMM的精髓。 ####
51 6
|
1月前
|
安全 Java 程序员
深入理解Java内存模型与并发编程####
本文旨在探讨Java内存模型(JMM)的复杂性及其对并发编程的影响,不同于传统的摘要形式,本文将以一个实际案例为引子,逐步揭示JMM的核心概念,包括原子性、可见性、有序性,以及这些特性在多线程环境下的具体表现。通过对比分析不同并发工具类的应用,如synchronized、volatile关键字、Lock接口及其实现等,本文将展示如何在实践中有效利用JMM来设计高效且安全的并发程序。最后,还将简要介绍Java 8及更高版本中引入的新特性,如StampedLock,以及它们如何进一步优化多线程编程模型。 ####
37 0
|
2月前
|
存储 算法 Java
Java内存管理深度剖析与优化策略####
本文深入探讨了Java虚拟机(JVM)的内存管理机制,重点分析了堆内存的分配策略、垃圾回收算法以及如何通过调优提升应用性能。通过案例驱动的方式,揭示了常见内存泄漏的根源与解决策略,旨在为开发者提供实用的内存管理技巧,确保应用程序既高效又稳定地运行。 ####
|
1月前
|
存储 监控 算法
Java内存管理深度剖析:从垃圾收集到内存泄漏的全面指南####
本文深入探讨了Java虚拟机(JVM)中的内存管理机制,特别是垃圾收集(GC)的工作原理及其调优策略。不同于传统的摘要概述,本文将通过实际案例分析,揭示内存泄漏的根源与预防措施,为开发者提供实战中的优化建议,旨在帮助读者构建高效、稳定的Java应用。 ####
48 8
|
1月前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。
|
1月前
|
存储 算法 Java
Java 内存管理与优化:掌控堆与栈,雕琢高效代码
Java内存管理与优化是提升程序性能的关键。掌握堆与栈的运作机制,学习如何有效管理内存资源,雕琢出更加高效的代码,是每个Java开发者必备的技能。
79 5
|
1月前
|
存储 算法 Java
Java内存管理深度解析####
本文深入探讨了Java虚拟机(JVM)中的内存分配与垃圾回收机制,揭示了其高效管理内存的奥秘。文章首先概述了JVM内存模型,随后详细阐述了堆、栈、方法区等关键区域的作用及管理策略。在垃圾回收部分,重点介绍了标记-清除、复制算法、标记-整理等多种回收算法的工作原理及其适用场景,并通过实际案例分析了不同GC策略对应用性能的影响。对于开发者而言,理解这些原理有助于编写出更加高效、稳定的Java应用程序。 ####
|
1月前
|
安全 Java 程序员
Java内存模型的深入理解与实践
本文旨在深入探讨Java内存模型(JMM)的核心概念,包括原子性、可见性和有序性,并通过实例代码分析这些特性在实际编程中的应用。我们将从理论到实践,逐步揭示JMM在多线程编程中的重要性和复杂性,帮助读者构建更加健壮的并发程序。
|
2月前
|
安全 Java
Java中WAIT和NOTIFY方法调用时机的深层解析
在Java多线程编程中,`wait()`和`notify()`方法的正确使用对于线程间的协调至关重要。这两个方法必须在同步块或同步方法中调用,这一规定的深层原因是什么呢?本文将深入探讨这一机制。
55 5
|
2月前
|
算法 Java 开发者
Java内存管理与垃圾回收机制深度剖析####
本文深入探讨了Java虚拟机(JVM)的内存管理机制,特别是其垃圾回收机制的工作原理、算法及实践优化策略。不同于传统的摘要概述,本文将以一个虚拟的“城市环卫系统”为比喻,生动形象地揭示Java内存管理的奥秘,旨在帮助开发者更好地理解并调优Java应用的性能。 ####

热门文章

最新文章