JMM做了什么 JMM(java memory model)java内存模型,它并没有实际的体现,它是一个规则,都知道ava是跨平台语言,在个操作系统中内存都有一定的差异性,每个系统的并发不一致,JMM 同时JMM也规范了JVM如何与计算机内存进行交互。JMM就是Java自己的一套协议来屏蔽掉各种硬件和操作系统的内存访问差异,实现平台一致性达到最终的"一次编写,到处运行" 2. JMM抽象图 上面的抽象图可以看到共享变量是在主内存里,但是在修改的时候线程会将变量拷贝到自己的工作空间内,修改后再刷回住内存的这样一个概念,中间线程操作变量是由JMM控制的,下面看一下它的规则。 通信 上面所说的步骤其实就是实现了线程之间的通信,但是不要以为线程之间的通信就是这么简单的,其实在Java中JMM内存模型定义了八种操作来实现同步的细节。 同时在Java内存模型中明确规定了要执行这些操作需要满足以下规则: 不允许read和load、store和write的操作单独出现。
CPU 与内存交互图片组成结构图图片JVM 内存模型内存模型图图片内存模型程序计数器(线程私有): 是当前线程锁执行字节码的行号治时期,每条线程都有一个独立的程序计数器 Java 内存模型 JMMJMM 是什么JMM(Java Memory Model) 简称 JMM 定义了 Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式, 制定的一种规范。 Java 内存模型,就是为了屏蔽系统和硬件的差异,让一套代码在不同平台下能到达相同的访问结果。JMM 从 Java 5 开始的 JSR-133 发布后,已经成熟和完善起来。 模型图图片主要划分主内存在 JMM 中主内存属于共享数据区域,对应着 JVM 中堆和方法区。Java 内存模型中规定所有变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问。 图片同时同一个 CPU 也从内存当中读取数据, 此时读取的结构可能是 1 也可能是 2, 如果 CPU1 把写的结果写到到内存中, CPU2 读取的就是 2, 如果 CPU1 没有把结果写回到主内存当中
Java内存模型即Java Memory Model,简称JMM。JMM定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式。JVM是整个计算机虚拟模型,所以JMM是隶属于JVM的。 Java内存模型 上面讲到了Java线程之间的通信采用的是过共享内存模型,这里提到的共享内存模型指的就是Java内存模型(简称JMM),JMM决定一个线程对共享变量的写入何时对另一个线程可见。 本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。 从上图来看,线程A与线程B之间如要通信的话,必须要经历下面2个步骤: 1. 首先,线程A把本地内存A中更新过的共享变量刷新到主内存中去。 2. 然后,线程B到主内存中去读取线程A之前已更新过的共享变量。 JMM通过控制主内存与每个线程的本地内存之间的交互,来为java程序员提供内存可见性保证。 上面也说到了,Java内存模型只是一个抽象概念,那么它在Java中具体是怎么工作的呢?
CPU缓存策略原理 缓存概述 CPU为了提升执行效率,减少CPU与内存的交互(交互影响CPU效率),一般在CPU上集成了多级缓存架构 cpu缓存策略图 cpu读取数据时, 会先从自己的寄存器当中读取. 1ns` L1 cache (一级缓存) `约1ns` L2 cache(二级缓存) `约3ns` L3cache(三级缓存) `约15ns` 主内存(最终存储地址) `约80ns` 缓存是由最小的存储区块缓存行Cache Line组成 2. 当中 进行数据的修改,把i修改为2 一、同时同一个cpu也从内存当中读取数据 此时读取的结构可能是1也可能是2 如果cpu1把写的结果写到到内存中, cpu2读取的就是2 如果cpu1没有把结果写回到主内存当中 ,cpu2读取的就是1 cpu缓存一致性解决方案 1.总线加锁 cpu1在读取的时候不允许其它cpu进行读取 弊端: 降低了cpu的吞吐量 2.缓存上的一致性协议MESI 后续再说MESI先有个印象
Java内存模型(JMM) 简介 Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能保证效果一致的机制及规范 2、指令级并行的重排序。现代处理器采用了指令级并行技术来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。 3、内存系统的重排序。 JMM主要解决的问题: 解决由于多线程通过共享内存进行通信时,存在的本地内存数据不一致、编译器会对代码指令重排序、处理器会对代码乱序执行等带来的问题 缓存一致性问题其实就是可见性问题。 处理器优化是可以导致原子性问题 指令重排即会导致有序性问题 数据同步八大原子操作 (1)lock(锁定):作用于主内存的变量,把一个变量标记为一条线程独占状态 (2)unlock(解锁):作用于主内存的变量 2、在顺序一致性内存模型中,每个操作都必须原子执行且立刻对所有线程可见。
二、JMM 为了保证JMM可以屏蔽硬件中内存和处理器的差异,所以可以发现Java的内存模型与硬件的内存结构是类似的,在JMM中也存在主内存、工作内存(高速缓存)、处理器线程(处理器)。 并且在JMM中也存在重排策略,并且比硬件中的重排策略优化性更高、更加细致。 Java内存模型结构如下图: ? 但是如果连续遇到了2次monitorexit时表示线程是遇到了异常而释放的锁。 · 可见性 可见性表示一个线程修改了变量值后可立即将新值同步到共享内存中。 (2)指令并行重排:在不存在语句依赖关系的情况下,处理器会重新安排语句的执行顺序。 (3)内存系统的重排:处理器和主内存中由于工作内存的存在会导致缓存与内存的同步存在时间差。 四、总结 JMM模型中允许主内存和工作线程中存在运行性能与工作线程相似的高速缓存。
JVM规范中试图定义一种Java内存模型(Java Memory Model,简称 JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果。 原则: JMM的关键技术点都是围绕多线程的原子性、可见性和有序性展开的 作用: 通过JMM来实现线程和主内存之间的抽象关系。 ,而Java内存模型中规定所有的变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问,但线程对变量的操作(读取赋值等)必须在工作内存中进行,首先要将变量从主内存拷贝到线程自己的工作内存空间,然后对变量进行操作 CPU的缓存,比如寄存器、L1、L2、L3缓存等) ---- 总结 我们定义的所有共享变量都存储在物理主内存中 每个线程都有自己独立的工作内存,里面保存该线程使用到的变量的副本(主内存中该变量的一份拷贝 如果重排序之后的执行结果与按照happens-before关系来执行的结果一致,那么这种重排序 并不非法 例如: 1+2+3 = 3+2+1,最终结果是一致的 happens-before之8条 次序规则
什么是Java内存模型JMM本身只是一个抽象的概念,并不真实存在,它描述的是一种规则或规范;通过这组规范,定义了程序中对各种变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。 需要每个JVM的实现都要遵守这样的规范;有了JMM规范的保障后,并发程序运行在不同虚拟机上时,得到的程序结果才是安全可靠可信赖的,如果没有JMM内存模型来规范,那经过不同JVM翻译之后,就可能出现,运行结果不相同或不正确 简单说JMM就是屏蔽了各种硬件和操作系统的访问差异,保证Java程序在各种平台下对内存的访问都能保证效果一致的机制规范。 三大特性JMM有三大特性:原子性、可见性、有序性原子性JMM保证了对共享变量的读取和写入可以被视为原子操作为支持JMM,Java定义了8种原子操作,用来控制主存和工作内存之间的交互read读取:作用于主内存 在JVM中,栈负责运行(主要是方法),堆中负责存储(比如new的对象),JVM运行程序的实体是线程,每个线程创建时,JVM都会为其创建一个工作内存,工作内存是每个现场私有数据区域;而Java内存模型中规定
目录 一、JMM内存模型产生的背景? 二、什么是JMM内存模型? 三、JMM内存模型用来解决什么问题? 四、JMM内存模型与JVM内存模型有什么关系? ---- 一、JMM内存模型产生的背景? JMM(Java内存模型)源于物理机器CPU架构的内存模型,最初用于解决MP(多处理器架构)系统中的缓存一致性问题,而JVM为了屏蔽各个硬件平台和操作系统对内存访问机制的差异化,提出了JMM的概念。 三、JMM内存模型用来解决什么问题? 1、JMM是Java物理内存模型 现代计算机通常有 2 个或更多 CPU。其中一些 CPU 也可能具有多个内核。关键是,在具有 2 个或更多 CPU 的现代计算机上,可能同时运行多个线程。 3、JMM内存模型和JVM运行时内存模型的关系 Java运行时内存模型和计算机物理内存结构是不一样的。计算机物理内存结构并不区分栈和堆。在物理内存结构中,栈和堆都位于主存中。
JMM对程序员屏蔽了CPU以及OS内存的使用问题,能够使程序在不同的CPU和OS内存上都能够达到预期的效果。 Java采用内存共享的模式来实现线程之间的通信。 同时顺序一致性是一个比较理想化的参考模型,它为我们提供了强大而又有力的内存可见性保证,他主要有两个特征:1 一个线程中的所有操作必须按照程序的顺序来执行;2 所有线程都只能看到一个单一的操作执行顺序,在顺序一致性模型中 Java 内存模型中定义了以下 8 种操作来完成主内存与工作内存之间交互的实现细节: luck(锁定):作用于主内存的变量,它把一个变量标示为一条线程独占的状态。 对一个变量执行 unlock 操作之前,必须先把此变量同步回主内存(执行 store 和 write 操作)。 关于JMM,这里分析下2个小问题? 1、普通的写操作,什么时候同步到主内存 2、普通的写操作同步到主内存时,对其他线程的本地内存有无影响 Java线程运行时有一块私有内存,当操作变量时,会将变量从主内存同步到私有内存,之后变量操作都是在私有内存中
简介 Java内存模型规范了Java虚拟机与计算机内存是如何协同工作的。Java虚拟机是一个完整的计算机的一个模型,因此这个模型自然也包含一个内存模型——又称为Java内存模型。 2、指令级并行的重排序。现代处理器采用了指令级并行技术来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。 3、内存系统的重排序。 Java内存模型(JMM) Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能保证效果一致的机制及规范 保证可见性 Java内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值的这种依赖主内存作为传递媒介的方式来实现的。 2.volatile 规则:volatile 变量的写,先发生于读,这保证了 volatile 变量的可见性。 3.锁规则:解锁(unlock) 必然发生在随后的加锁(lock)前。
JMM简介 Java Memory Model简称JMM, 是一系列的Java虚拟机平台对开发者提供的多线程环境下的内存可见性、是否可以重排序等问题的无关具体平台的统一的保证。 并发编程有多种风格,除了CSP(通信顺序进程)、Actor等模型外,大家最熟悉的应该是基于线程和锁的共享内存模型了。 在JDK1.5之前,Java的内存模型有着严重的问题,例如在旧的内存模型中,一个线程可能在构造器执行完成后看到一个final字段的默认值、volatile字段的写入可能会和非volatile字段的读写重排序 所以在JDK1.5中,通过JSR133提出了新的内存模型,修复之前出现的问题。 (如flush到内存)先于Load2和之后的load的数据的加载。
就Java内存模型而言,它是深入了解Java并发编程的先决条件。对于后续多线程中的线程安全、同步异步处理等更是大有裨益。 硬件内存架构 在学习Java内存模型之前,先了解一下计算机硬件内存模型。 Java内存模型 Java内存模型即Java Memory Model,简称JMM。用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各平台下都能够达到一致的内存访问效果。 JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本 本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。 ? JMM与Java内存结构并不是同一个层次的内存划分,两者基本没有关系。 由于工作内存是每个线程的私有数据,线程间无法相互访问工作内存,因此存储在工作内存的数据不存在线程安全问题。 JMM模型与硬件模型直接的对照关系可简化为下图: ?
JMM简介 Java Memory Model简称JMM, 是一系列的Java虚拟机平台对开发者提供的多线程环境下的内存可见性、是否可以重排序等问题的无关具体平台的统一的保证。 并发编程有多种风格,除了CSP(通信顺序进程)、Actor等模型外,大家最熟悉的应该是基于线程和锁的共享内存模型了。 在JDK1.5之前,Java的内存模型有着严重的问题,例如在旧的内存模型中,一个线程可能在构造器执行完成后看到一个final字段的默认值、volatile字段的写入可能会和非volatile字段的读写重排序 所以在JDK1.5中,通过JSR133提出了新的内存模型,修复之前出现的问题。 (如flush到内存)先于Load2和之后的load的数据的加载。
而在这些操作协议下,对特定的内存或高速缓存进行读写访问的过程,就是内存模型。不同架构(ARM/X86等)的物理机有不同的内存模型。 为了屏蔽不同架构的机器上的内存访问差异,让Java程序在各种平台下都能达到一致的内存访问效果,所以Java也制定了一套内存操作协议,即Java内存模型。JMM保证了多线程下变量的缓存一致性。 工作内存和主内存 JMM主要目标是定义程序中各个变量的访问规则,即在JVM中将变量存储到内存和从内存中取出变量这样的底层细节,来实现缓存一致性。 JMM在定义上将内存分为主内存和工作内存,主内存对应Heap,属于线程公有,工作内存对应虚拟机栈,属于每个线程私有。 工作内存无法互相访问 工作内存保存了线程用到的变量的主内存副本拷贝 原子操作 既然JMM规定了变量在主内存和工作内存中如何传输和操作,同时也提供了八个原子指令来具体实现细节。
主内存和工作内存: Java内存模型的主要目标是定义程序中各个变量的访问规则,即在JVM中将变量存储到内存和从内存中取出变量这样的底层细节。 JMM规定了所有的变量都存储在主内存(Main Memory)中。 线程1和线程2要想进行数据的交换一般要经历下面的步骤: 1.线程1把工作内存1中的更新过的共享变量刷新到主内存中去。 2.线程2到主内存中去读取线程1刷新过的共享变量,然后copy一份到工作内存2中去。 Java内存模型是通过将在工作内存中的变量修改后的值同步到主内存,在读取变量前从主内存刷新最新值到工作内存中,这种依赖主内存的方式来实现可见性的。
JMM(Java内存模型Java Memory Model,简称JMM)本身是一种抽象的概念并不真实存在,它描述的是一组规则或规范,它定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式以及关于同步的约定 JMM关于同步的规定: 线程解锁前,必须把共享变量的值刷新回主内存 线程加锁前,必须读取主内存的最新值到自己的工作内存 加锁解锁是同一把 Java线程之间的通信由Java内存模型(本文简称为JMM)控制 ,JMM决定一个线程对共享变量的写入何时对另一个线程可见,由于JVM运行程序的实体是线程,而每个线程创建时JVM都会为其创建一个工作内存(有些地方称为栈空间),工作内存是每个线程的私有数据区域,而Java 内存模型中规定所有变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问,但线程对变量的操作(读取赋值等)必须在工作内存中进行,首先要将变量从主内存拷贝的自己的工作内存空间,然后对变量进行操作,操作完成后再将变量写回主内存 ,由于JMM的可见性,其他线程会立即知道主内存的值已经被更新,其多线程简要访问过程如下图: image.png JMM涉及的指令以此为read,load,use,assign,store,writer
answer : JVM 定义了 JMM 用于屏蔽各种硬件与操作系统的内存访问差异,实现 JVM 跨平台达到一致的内存访问效果 Java 内存模型 JavaMemoryModel JMM (Java 内存模型 JavaMomary Model,简称 JMM), 本身是一种抽象的概念并不真实存在,仅仅描述了一组约定或规范,(本质) 通过这组规范定义了程序中(特别是多线程)各个变量的读写访问方式 JMM 规范规定所有变量都存储在主内存中 读写过程 线程 A 先从主内存中读取到一个共享变量到自己的线程域内存中,作为本地共享变量的副本 在本地线程域内存对本地共享变量进行修改 将修改后的数据写回到主内存中 (又称为栈空间) 工作内存是每个线程的私有数据区 Java 内存模型规定所有的变量均存储在主内存中 主内存是共享内存区域,所有线程均可访问 线程对于变量的操作须在工作内存中进行 首先将主内存的变量复制到工作内存中 但是无法确认 B 线程最终得到的结果 该代码是线程不安全的 修复方案 1 加锁,将 get 和 set 方法加上悲观锁 弊端,写读均为独占锁,读操作使得代码效率下降,适合并发量小的场景 修复方案 2
ctorInstance(memory); //2:初始化对象 instance = memory; //3:设置instance指向刚分配的内存地址 而代码中的2和3之间,可能会被重排序。 多线程内存模型 通俗来说,JMM是一套多线程读写共享数据时,对数据的可见性,有序性和原子性的规则。 Java多线程内存模型跟cpu缓存模型类似,是基于cpu缓存模型来建立的。Java线程内存模型是标准化的,屏蔽掉了底层不同计算机的区别。 JMM数据原子操作 read(读取)︰从主内存读取数据 load(载入)︰将主内存读取到的数据写入工作内存. use(使用)∶从工作内存读取数据来计算 assign(赋值)∶将计算好的值重新赋值到工作内存中 Java内存模型别再傻傻分不清了:https://blog.csdn.net/qq_41170102/article/details/104650162 双重检查锁定(DCL)与延迟初始化:https:
java内存模型 jmm(java memory model)规范,他规范了java虚拟机与计算机内存如何协调工作 ,他规定了一个线程如何及何时看到其他线程修改过的变量的值,以及在必须时,如何同步的访问共享变量 ,私有本地工作内存是jmm模型抽象概念,并不是真实存在的,她涵盖了缓存,协缓存区,寄存器以及其他的硬件和编译器的优化,本地内存中存储了该线程以读或写共享变量的拷贝的副本,比如线程1 要使用主内存中的变量 模型是对内存的物理划分,只局限在内存,只局限在jvm内存。 java内存模型 – 同步操作与规则 Java内存模型-同步八种操作 lock(锁定):作用于主内存的变量,把一个变量标识为一条线程独占状态 unlock(解锁):作用于主内存的变量,把一个处于锁定状态的变量释放出来 , 把工作内存中的一个变量的值传送到主内存中 , 以便随后的write的操作 write (写入) : 作用于主内存的变量, 它把store操作从工作内存中一个变量的值传送到主内存的变量中 Java内存模型