JMM做了什么 JMM(java memory model)java内存模型,它并没有实际的体现,它是一个规则,都知道ava是跨平台语言,在个操作系统中内存都有一定的差异性,每个系统的并发不一致,JMM 同时JMM也规范了JVM如何与计算机内存进行交互。JMM就是Java自己的一套协议来屏蔽掉各种硬件和操作系统的内存访问差异,实现平台一致性达到最终的"一次编写,到处运行" 2. JMM抽象图 上面的抽象图可以看到共享变量是在主内存里,但是在修改的时候线程会将变量拷贝到自己的工作空间内,修改后再刷回住内存的这样一个概念,中间线程操作变量是由JMM控制的,下面看一下它的规则。 通信 上面所说的步骤其实就是实现了线程之间的通信,但是不要以为线程之间的通信就是这么简单的,其实在Java中JMM内存模型定义了八种操作来实现同步的细节。 同时在Java内存模型中明确规定了要执行这些操作需要满足以下规则: 不允许read和load、store和write的操作单独出现。
CPU 与内存交互图片组成结构图图片JVM 内存模型内存模型图图片内存模型程序计数器(线程私有): 是当前线程锁执行字节码的行号治时期,每条线程都有一个独立的程序计数器 这个区域的内存回收目标主要针对常量池的回收和堆类型的卸载。JMM 与 JVMJMM 与 JVM 内存区域的划分是不同的概念层次。JMM 描述的是一组规则。 Java 内存模型 JMMJMM 是什么JMM(Java Memory Model) 简称 JMM 定义了 Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式, 制定的一种规范。 Java 内存模型,就是为了屏蔽系统和硬件的差异,让一套代码在不同平台下能到达相同的访问结果。JMM 从 Java 5 开始的 JSR-133 发布后,已经成熟和完善起来。 模型图图片主要划分主内存在 JMM 中主内存属于共享数据区域,对应着 JVM 中堆和方法区。Java 内存模型中规定所有变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问。
Java内存模型即Java Memory Model,简称JMM。JMM定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式。JVM是整个计算机虚拟模型,所以JMM是隶属于JVM的。 Java内存模型 上面讲到了Java线程之间的通信采用的是过共享内存模型,这里提到的共享内存模型指的就是Java内存模型(简称JMM),JMM决定一个线程对共享变量的写入何时对另一个线程可见。 JMM通过控制主内存与每个线程的本地内存之间的交互,来为java程序员提供内存可见性保证。 上面也说到了,Java内存模型只是一个抽象概念,那么它在Java中具体是怎么工作的呢? 为了更好的理解上Java内存模型工作方式,下面就JVM对Java内存模型的实现、硬件内存模型及它们之间的桥接做详细介绍。 Java内存模型和硬件架构之间的桥接 正如上面讲到的,Java内存模型和硬件内存架构并不一致。
CPU缓存策略原理 缓存概述 CPU为了提升执行效率,减少CPU与内存的交互(交互影响CPU效率),一般在CPU上集成了多级缓存架构 cpu缓存策略图 cpu读取数据时, 会先从自己的寄存器当中读取. 如果没有再从Cache当中读取数据.如果Cache当中也没能.再从内存当中获取.然后再依次缓存 多核CPU结构图 三级缓存 L1 Cache 分为数据缓存和指令缓存,逻辑核独占 CPU所有操作的数据全部在寄存器当中完成 Registers(寄存器组) `<1ns` L1 cache (一级缓存) `约1ns` L2 cache(二级缓存) `约3ns` L3cache(三级缓存) `约15ns` 主内存 计算机当中为了让效率更高,在读取数据时,是一块一块进行读取的 3. cache Line能够读取的大小是64个字节 cpu缓存一致性问题 假设cpu1从主内存当中读取一个共享数据i = 1,读取到cache 当中 进行数据的修改,把i修改为2 一、同时同一个cpu也从内存当中读取数据 此时读取的结构可能是1也可能是2 如果cpu1把写的结果写到到内存中, cpu2读取的就是2 如果cpu1没有把结果写回到主内存当中
什么是Java内存模型JMM本身只是一个抽象的概念,并不真实存在,它描述的是一种规则或规范;通过这组规范,定义了程序中对各种变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。 需要每个JVM的实现都要遵守这样的规范;有了JMM规范的保障后,并发程序运行在不同虚拟机上时,得到的程序结果才是安全可靠可信赖的,如果没有JMM内存模型来规范,那经过不同JVM翻译之后,就可能出现,运行结果不相同或不正确 简单说JMM就是屏蔽了各种硬件和操作系统的访问差异,保证Java程序在各种平台下对内存的访问都能保证效果一致的机制规范。 三大特性JMM有三大特性:原子性、可见性、有序性原子性JMM保证了对共享变量的读取和写入可以被视为原子操作为支持JMM,Java定义了8种原子操作,用来控制主存和工作内存之间的交互read读取:作用于主内存 在JVM中,栈负责运行(主要是方法),堆中负责存储(比如new的对象),JVM运行程序的实体是线程,每个线程创建时,JVM都会为其创建一个工作内存,工作内存是每个现场私有数据区域;而Java内存模型中规定
JVM规范中试图定义一种Java内存模型(Java Memory Model,简称 JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果。 原则: JMM的关键技术点都是围绕多线程的原子性、可见性和有序性展开的 作用: 通过JMM来实现线程和主内存之间的抽象关系。 ,而Java内存模型中规定所有的变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问,但线程对变量的操作(读取赋值等)必须在工作内存中进行,首先要将变量从主内存拷贝到线程自己的工作内存空间,然后对变量进行操作 ,操作完成后再将变量写回主内存,不能直接操作主内存中的变量,各个线程中的工作内存中存储着主内存中的变量副本拷贝,因此不同的线程间无法访问对方的工作内存,线程间的通信(传值)必须通过主内存来完成 JMM 依赖这个原则,我们可以通过几条简单规则一下子解决并发环境下两个操作之间是否可能存在冲突的所有问题 ,而不需要陷入Java内存模型苦涩难懂的底层编译原理之中。
二、JMM 为了保证JMM可以屏蔽硬件中内存和处理器的差异,所以可以发现Java的内存模型与硬件的内存结构是类似的,在JMM中也存在主内存、工作内存(高速缓存)、处理器线程(处理器)。 并且在JMM中也存在重排策略,并且比硬件中的重排策略优化性更高、更加细致。 Java内存模型结构如下图: ? JMM与硬件内存结构相似,他规定了所有的变量都存储在主内存中,所有的运算处理都在线程中完成,并且每条线程都有自己的工作内存,在工作时每个工作内存保存了线程所需要用到的变量的拷贝。 · 可见性 可见性表示一个线程修改了变量值后可立即将新值同步到共享内存中。在JMM中提供了关键字volatile、synchronized来保证线程操作的可见性。 四、总结 JMM模型中允许主内存和工作线程中存在运行性能与工作线程相似的高速缓存。
Java内存模型(JMM) 简介 Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能保证效果一致的机制及规范 JVM运行程序的实体是线程,而每个线程创建时JVM都会为其创建一个工作内存(有些地方称为栈空间),用于存储线程私有的数据,而Java内存模型中规定所有变量都存储在主内存,主内存是共享内存区域, 所有线程都可以访问 JMM主要解决的问题: 解决由于多线程通过共享内存进行通信时,存在的本地内存数据不一致、编译器会对代码指令重排序、处理器会对代码乱序执行等带来的问题 缓存一致性问题其实就是可见性问题。 保证可见性 Java内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值的这种依赖主内存作为传递媒介的方式来实现的。 2、在顺序一致性内存模型中,每个操作都必须原子执行且立刻对所有线程可见。
目录 一、JMM内存模型产生的背景? 二、什么是JMM内存模型? 三、JMM内存模型用来解决什么问题? 四、JMM内存模型与JVM内存模型有什么关系? ---- 一、JMM内存模型产生的背景? JMM(Java内存模型)源于物理机器CPU架构的内存模型,最初用于解决MP(多处理器架构)系统中的缓存一致性问题,而JVM为了屏蔽各个硬件平台和操作系统对内存访问机制的差异化,提出了JMM的概念。 三、JMM内存模型用来解决什么问题? 6)对一个变量执行unlock操作之前,必须先把此变量同步到主内存中(执行store和write操作) 四、JMM内存模型与JVM内存模型有什么关系? 3、JMM内存模型和JVM运行时内存模型的关系 Java运行时内存模型和计算机物理内存结构是不一样的。计算机物理内存结构并不区分栈和堆。在物理内存结构中,栈和堆都位于主存中。
简介 Java内存模型规范了Java虚拟机与计算机内存是如何协同工作的。Java虚拟机是一个完整的计算机的一个模型,因此这个模型自然也包含一个内存模型——又称为Java内存模型。 为什么要有内存模型 现代的计算机有多级缓存 ? 在CPU访问存储设备时,无论是存取数据抑或存取指令,都趋于聚集在一片连续的区域中,这就被称为局部性原理。 Java内存模型(JMM) Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能保证效果一致的机制及规范 为了保证共享内存的正确性(可见性、有序性、原子性),内存模型定义了共享内存系统中多线程程序读写操作行为的规范。通过这些规则来规范对内存的读写操作,从而保证指令执行的正确性。 保证可见性 Java内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值的这种依赖主内存作为传递媒介的方式来实现的。
JMM规定了线程的工作内存和主内存之间的交互关系,以及线程之间的可见性和程序的执行顺序。一方面,要为程序员提供足够强的内存可见性保证;另一方面,对编译器和处理器的限制要尽可能地放松。 JMM对程序员屏蔽了CPU以及OS内存的使用问题,能够使程序在不同的CPU和OS内存上都能够达到预期的效果。 Java采用内存共享的模式来实现线程之间的通信。 同时顺序一致性是一个比较理想化的参考模型,它为我们提供了强大而又有力的内存可见性保证,他主要有两个特征:1 一个线程中的所有操作必须按照程序的顺序来执行;2 所有线程都只能看到一个单一的操作执行顺序,在顺序一致性模型中 Java 内存模型中定义了以下 8 种操作来完成主内存与工作内存之间交互的实现细节: luck(锁定):作用于主内存的变量,它把一个变量标示为一条线程独占的状态。 Java 内存模型还规定了执行上述 8 种基本操作时必须满足如下规则: 不允许 read 和 load、store 和 write 操作之一单独出现,以上两个操作必须按顺序执行,但没有保证必须连续执行,
JMM简介 Java Memory Model简称JMM, 是一系列的Java虚拟机平台对开发者提供的多线程环境下的内存可见性、是否可以重排序等问题的无关具体平台的统一的保证。 并发编程有多种风格,除了CSP(通信顺序进程)、Actor等模型外,大家最熟悉的应该是基于线程和锁的共享内存模型了。 在JDK1.5之前,Java的内存模型有着严重的问题,例如在旧的内存模型中,一个线程可能在构造器执行完成后看到一个final字段的默认值、volatile字段的写入可能会和非volatile字段的读写重排序 所以在JDK1.5中,通过JSR133提出了新的内存模型,修复之前出现的问题。 HappenBefore 前面提到的各种内存屏障对应开发者来说还是比较复杂底层,因此JMM又可以使用一系列HappenBefore的偏序关系的规则方式来说明,要想保证执行操作B的线程看到操作A的结果(无论
JMM简介 Java Memory Model简称JMM, 是一系列的Java虚拟机平台对开发者提供的多线程环境下的内存可见性、是否可以重排序等问题的无关具体平台的统一的保证。 并发编程有多种风格,除了CSP(通信顺序进程)、Actor等模型外,大家最熟悉的应该是基于线程和锁的共享内存模型了。 在JDK1.5之前,Java的内存模型有着严重的问题,例如在旧的内存模型中,一个线程可能在构造器执行完成后看到一个final字段的默认值、volatile字段的写入可能会和非volatile字段的读写重排序 所以在JDK1.5中,通过JSR133提出了新的内存模型,修复之前出现的问题。 HappenBefore 前面提到的各种内存屏障对应开发者来说还是比较复杂底层,因此JMM又可以使用一系列HappenBefore的偏序关系的规则方式来说明,要想保证执行操作B的线程看到操作A的结果(无论
就Java内存模型而言,它是深入了解Java并发编程的先决条件。对于后续多线程中的线程安全、同步异步处理等更是大有裨益。 硬件内存架构 在学习Java内存模型之前,先了解一下计算机硬件内存模型。 Java内存模型 Java内存模型即Java Memory Model,简称JMM。用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各平台下都能够达到一致的内存访问效果。 JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本 本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。 ? JMM与Java内存结构并不是同一个层次的内存划分,两者基本没有关系。 由于工作内存是每个线程的私有数据,线程间无法相互访问工作内存,因此存储在工作内存的数据不存在线程安全问题。 JMM模型与硬件模型直接的对照关系可简化为下图: ?
在Java语言中,采用的是共享内存模型来实现多线程之间的信息交换和数据同步的。 线程之间通过共享程序公共的状态,通过读-写内存中公共状态的方式来进行隐式的通信。 在说Java内存模型之前,我们先说一下Java的内存结构,也就是运行时的数据区域: Java虚拟机在执行Java程序的过程中,会把它管理的内存划分为几个不同的数据区域,这些区域都有各自的用途、创建时间、 主内存和工作内存: Java内存模型的主要目标是定义程序中各个变量的访问规则,即在JVM中将变量存储到内存和从内存中取出变量这样的底层细节。 JMM规定了所有的变量都存储在主内存(Main Memory)中。 Java内存模型是通过将在工作内存中的变量修改后的值同步到主内存,在读取变量前从主内存刷新最新值到工作内存中,这种依赖主内存的方式来实现可见性的。
而在这些操作协议下,对特定的内存或高速缓存进行读写访问的过程,就是内存模型。不同架构(ARM/X86等)的物理机有不同的内存模型。 为了屏蔽不同架构的机器上的内存访问差异,让Java程序在各种平台下都能达到一致的内存访问效果,所以Java也制定了一套内存操作协议,即Java内存模型。JMM保证了多线程下变量的缓存一致性。 工作内存和主内存 JMM主要目标是定义程序中各个变量的访问规则,即在JVM中将变量存储到内存和从内存中取出变量这样的底层细节,来实现缓存一致性。 JMM在定义上将内存分为主内存和工作内存,主内存对应Heap,属于线程公有,工作内存对应虚拟机栈,属于每个线程私有。 工作内存无法互相访问 工作内存保存了线程用到的变量的主内存副本拷贝 原子操作 既然JMM规定了变量在主内存和工作内存中如何传输和操作,同时也提供了八个原子指令来具体实现细节。
JMM(Java内存模型Java Memory Model,简称JMM)本身是一种抽象的概念并不真实存在,它描述的是一组规则或规范,它定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式以及关于同步的约定 JMM关于同步的规定: 线程解锁前,必须把共享变量的值刷新回主内存 线程加锁前,必须读取主内存的最新值到自己的工作内存 加锁解锁是同一把 Java线程之间的通信由Java内存模型(本文简称为JMM)控制 ,JMM决定一个线程对共享变量的写入何时对另一个线程可见,由于JVM运行程序的实体是线程,而每个线程创建时JVM都会为其创建一个工作内存(有些地方称为栈空间),工作内存是每个线程的私有数据区域,而Java 内存模型中规定所有变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问,但线程对变量的操作(读取赋值等)必须在工作内存中进行,首先要将变量从主内存拷贝的自己的工作内存空间,然后对变量进行操作,操作完成后再将变量写回主内存 ,由于JMM的可见性,其他线程会立即知道主内存的值已经被更新,其多线程简要访问过程如下图: image.png JMM涉及的指令以此为read,load,use,assign,store,writer
JMM CPU 对内存的读写操作的数据不一致性问题 CPU 对数据的操作由外存->内存->三级缓存 3 个阶段,对内存读写操作存在数据不一致问题 question : 如何解决因为硬件与操作系统数据读写速度不同导致的数据不一致问题 answer : JVM 定义了 JMM 用于屏蔽各种硬件与操作系统的内存访问差异,实现 JVM 跨平台达到一致的内存访问效果 Java 内存模型 JavaMemoryModel JMM (Java 内存模型 JavaMomary Model,简称 JMM), 本身是一种抽象的概念并不真实存在,仅仅描述了一组约定或规范,(本质) 通过这组规范定义了程序中(特别是多线程)各个变量的读写访问方式 JMM 规范规定所有变量都存储在主内存中 读写过程 线程 A 先从主内存中读取到一个共享变量到自己的线程域内存中,作为本地共享变量的副本 在本地线程域内存对本地共享变量进行修改 将修改后的数据写回到主内存中 (又称为栈空间) 工作内存是每个线程的私有数据区 Java 内存模型规定所有的变量均存储在主内存中 主内存是共享内存区域,所有线程均可访问 线程对于变量的操作须在工作内存中进行 首先将主内存的变量复制到工作内存中
内存模型就诞生了! 通过JMM保证java代码最终落地,实现的是一样的三兄弟区分JVM内存结构 VS Java内存模型 VS Java对象模型上面说到,因为java的平台无关性,衍生的问题,出现了java内存模型, ,无法保证并发安全假设java没有JMM内存模型,把代码用synchronized保护起来,不同平台处理,还是可能有问题的,所以就需要一个标准,让多线程运行的结果可预期,通过jmm的规范,规范没错JMM ,但是java语言屏蔽了细节,我们只需要考虑,JMM内存模型抽象出来的主内存和本地内存的概念。 ,规范了cpu和jvm在java的匹配,内存模型主要是重排序、可见性、原子性然后主要讲可见性了,说下jMM对内存的抽象, 讲happens-before,再说volatile和synchronized,
1 Java内存模型(JMM)的意义 内存模型描述程序的可能行为。 Java编程语言内存模型 通过检查执行跟踪中的每个读操作,并根据某些规则检查该读操作观察到的写操作是否有效来工作。 只要程序的所有执行产生的结果都可以由内存模型预测。 内存模型决定了在程序的每个点上可以读取什么值 1.1 Shared Variables 共享变量的描述 可以在线程之间共享的内存称为共享内存或堆内存 所有实例字段、静态字段和数组元素都存储在堆内存中 定义 2 主内存与工作内存 工作内存缓存 Java内存模型的主要目标是定义各个变量的访问规则 即在虚拟机中将变量存储到内存和从内存中取出变量值这样的底层细节 此处的变量包括了实例域,静态域和构成数组对象的元素 ,线程间变量值的传递均要通过主内存 JVM模型与JMM不是同一层次的内存划分,基本是没有关系的,硬要对应起来,从变量,内存,工作内存的定义来看 主内存 === Java堆中的对象实例数据部分 工作内存