内存模型 主存储器与工作存储器 主存储器 方法区(Method Area) 方法区用于存储类的信息, 常量, 静态变量, 即时编译器编译后的代码. 当方法区无法满足内存分配需求时, 将抛出OutOfMeoryError. 堆(Heap) 堆在虚拟器启动时创建, 是JVM所管理的内存中最大的一块, 主要用于存放对象实例, 几乎所有的对象实例都在这里进行分配. 栈(Java Virtual Machine Stacks) 代表着Java方法执行的内存模型, 每个方法执行时都会创建一个栈帧来存储方法的变量表, 操作数栈, 动态链接方法, 返回值, 返回地址等信息 这具体是由Java的执行系统决定. 同样的, 对于将值更新到字段的过程, 也是先将值赋给工作拷贝, 再由工作拷贝映像到主存储器上. 至于何时映像, 也是有Java执行系统决定.
什么是JMM JMM即为JAVA 内存模型(java memory model)。 Java内存模型,就是为了屏蔽系统和硬件的差异,让一套代码在不同平台下能到达相同的访问结果。JMM从java 5开始的JSR-133发布后,已经成熟和完善起来。 更多的时候,使用java的happen-before规则来进行分析。 模型特征 原子性:例如上面八项操作,在操作系统里面是不可分割的单元。 因为JMM的工作内存和主内存之间存在延迟,而且java会对一些指令进行重新排序。 int b; 6 7 static FinalConstructor finalConstructor; 8 9 public FinalConstructor() { 10
Java内存模型 Java内存模型是每个java程序员必须掌握理解的,这是Java的核心基础,对我们编写代码特别是并发编程时有很大帮助。 由于Java程序是交由JVM执行的,所以我们在谈Java内存区域划分的时候事实上是指JVM内存区域划分。 1.1. Java内存模型指的就是Runtime Data Area(运行时数据区),即程序执行期间用到的数据和相关信息保存区。 1.2. Java内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈、堆、方法区、程序计数器、本地方法栈五个部分。结构如下图: 1.2.1. PC程序计数器: l 每个线程对应有一个程序计数器。 Java内存模型工作示意图 1) 首先类加载器将Java代码加载到方法区 2) 然后执行引擎从方法区找到main方法 3) 为方法创建栈帧放入方法栈,同时创建该栈帧的程序计数器
JMM(Java内存模型)源于物理机器CPU架构的内存模型,最初用于解决MP(多处理器架构)系统中的缓存一致性问题,而JVM为了屏蔽各个硬件平台和操作系统对内存访问机制的差异化,提出了JMM的概念。 Java内存模型是一种虚拟机规范,JMM规范了Java虚拟机与计算机内存是如何协同工作的:规定了一个线程如何和何时可以看到由其他线程修改过后的共享变量的值,以及在必须时如何同步的访问共享变量。 Java内存模型(Java Memory Model简称JMM)是一种抽象的概念,并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式 2、JVM是运行时内存模型 在JVM内部使用java内存模型将内存氛围线程栈和堆,Java 虚拟机中运行的每个线程都有自己的线程堆栈。线程堆栈包含有关线程调用哪些方法以到达当前执行点的信息。 3、JMM内存模型和JVM运行时内存模型的关系 Java运行时内存模型和计算机物理内存结构是不一样的。计算机物理内存结构并不区分栈和堆。在物理内存结构中,栈和堆都位于主存中。
Java内存模型(简称JMM)指定了JVM如何利用计算机内存(RAM)进行工作。JMM与整个计算机的模型类似,这个模型自然也包含内存模型,即Java内存模型(AKA)。 由于最初的JMM无法胜任工作,因此在Java 1.5中对JMM进行了升级,该版本在Java 8中依然在使用。 那么,什么样的Java代码可以形成上图的情景呢?下面用简单的代码展示一下。 硬件内存结构 当代硬件内存结构与JVM内部的内存模型稍有不同。为了理解JMM如何与其打交道,知晓硬件内存结构十分重要。本部分描述了通用硬件内存结构,后续将讲述JMM如何与之协同工作。 那么,如果Java应用是多线程的,每个CPU都可以并发的运行一个线程。
参考链接: Java中的JVM的关闭挂钩 (原本准备把内存模型单独放到某一篇文章的某个章节里面讲解,后来查阅了国外很多文档才发现其实JVM内存模型的内容还蛮多的,所以直接作为一个章节的基础知识来讲解,可能该章节概念的东西比较多 简介 2.堆和栈 3.本机内存 4.防止内存泄漏 1.JMM简介 i.内存模型概述 Java平台自动集成了线程以及多处理器技术,这种集成程度比Java 究竟什么是内存模型? ,但是最终会发生,也就是说,Java内存模型中的可见性的特性主要是针对线程和线程之间使用内存的一种规则和约定,该约定由JMM定义。 【*:这里讨论的排序是最底层的内存里面执行的时候的NativeCode的排序,不是说按照顺序执行的Java代码具有的有序性质,本文主要分析的是JVM的内存模型,所以希望读者明白这里指代的讨论单元是内存区
转载请以链接形式标明出处: 本文出自:103style的博客 Java并发编程的艺术笔记 并发编程的挑战 Java并发机制的底层实现原理 Java内存模型 Java并发编程基础 Java中的锁的使用和实现介绍 Java并发容器和框架 Java中的12个原子操作类介绍 Java中的并发工具类 Java中的线程池 Executor框架 ---- 目录 内存模型基础 volatile的内存语义 锁的内存语义 final Java并发 采用的是 共享内存模型,Java线程之前的通信总是隐式进行的。 Java线程通信由Java内存模型(简称 JMM)控制,JMM 决定一个线程对共享变量的写入何时对另一个线程可见。 ---- Java内存模型综述 处理器的内存模型 顺序一致性内存模型 是一个 理论参考模型,JMM和处理器内存模型在设计时通常会以顺序一致性内存模型为参照。
我们可以通过对 1)内存可见性等问题产生的背景,2)以及Java对这些问题的解决思路来学习Java内存模型。
JUC 今天跟大佬交流了一下,聊到Java四种内存屏障,现在分享一下 一.内存屏障是为了限制重排序,所谓重排序,是编译器和处理器为了提高系统吞吐量,优化程序性能,而对指令顺序进行重排序 1.LoadLoad 模型 Load1 LoadLoad Load2 保证load1的数据的装载在load2以及后续装载指令的装载 2.StoreStore 模型 Store1 StoreStore Store2 保证Store1 数据可见(刷新到内存中) 先于 Store2以及后续指令的存储 3.LoadStore 模型 Load1 LoadStore Store2 保证Load1的数据装载先于Store2以及后续存储指令的刷新 4.StoreLoad 模型 Store1 StoreLoad Load2 保证Store1的数据刷新先于Load2以及后续装载指令。 只有当该内存屏障前的存储和装载完毕之后,才会通过屏障 补充: 数据加载与存储( Load-store )指令用于在存储器和处理器的寄存器之间传送数据。可以理解位加载是读,装载是写。
前言 在学习java多线程并发编程前,必须要了解java内存模型,只有了解java内存模型,才能知道为什么多线程并发时会出现数据不一致,什么时候需要加锁同步等各种问题。 下面只是简单阐述下java内存模型及其相关的概念。 内存模型简介 java的并发采用的是共享内存模型(而非消息传递模型)。 Java内存模型(Java Memory Model)描述了Java程序中各种变量(共享变量)的访问规则,以及在JVM中将变量存储到内存和从内存中读取变量这样的底层细节。 Java线程之间的通信由Java内存模型(JMM)控制,JMM决定一个线程对共享变量的写入何时对另一个线程可见。 本地内存是JMM的一个抽象概念,并不真实存在,它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。Java内存模型的抽象示意图如下: ? 内存模型 图中的共享变量为:实例变量和静态变量。
Java内存模型规定了所有的变量都存储在主内存中 每条线程还有自己的工作内存 线程的工作内存中保存了该线程中是用到的变量的主内存副本拷贝 线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存 -不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量的传递均需要自己的工作内存和主- 存之间进行数据同步进行
Java 内存模型试图屏蔽各种硬件和操作系统的内存访问差异,以实现让 Java 程序在各种平台下都能达到一致的内存访问效果。 文章目录 Java内存模型(JMM)的介绍 内存模型抽象结构 哪些是共享变量 JMM抽象结构模型 主内存与工作内存 内存间交互操作 内存模型三大特性 1. 原子性 2. 可见性 3. 传递性 Java内存模型(JMM)的介绍 什么是线程安全?在<<深入理解Java虚拟机>>中看到的定义。 如果程序员不能理解Java的共享内存模型在编写并发程序时一定会遇到各种各样关于内存可见性的问题。 Java 内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值来实现可见性的。
Java编译器、处理器都会保证单线程下的as-if-serial语义。 a = 1; //A 8 x = b; //B 9 } 10 public void setLower(int value) { 9 if (value > upper) 10 x.finalField = v; StoreStore; sharedRef = x; 双重检查锁定模型 双重检查锁定代码: 1 public class DoubleCheckLock 参考资料 《Java内存访问重排序的研究》https://tech.meituan.com/java-memory-reordering.html 《java并发编程的艺术》 《就是要你懂
什么是Java内存模型 java内存模型(JMM)全称为Java Memory Model,是java虚拟机为了java程序能够正常运行而制定的一套规范,规范中规定了JVM中的数据如何与RAM的数据进行交互 Java内存模型是怎样的 我们知道,在Java中,实例字段、静态字段和构成数组对象的元素是线程共享的,但局部变量与方法参数是线程私有的,不会被共享。 那在这里呢,Java 内存模型就定义了 8 种操作和 8 个规则。 回头想想,JMM 是一套规则呀,它只会给你定义规范,模型,具体的实现自己玩去!理解这一点很重要。 Java 内存模型只要求上述操作必须按顺序执行,而没有保证必须是连续执行。 Java 内存模型定义的 8 种操作,就要求虚拟机的实现每一步都必须是原子性的,即不可分割的。
一、硬件的内存模型和指令重排序 在讲解java虚拟机的内存模型之前,我们先了解一下硬件的内存模型和指令重排序。 不同架构的屋里机器可以拥有不一样的内存模型,而Java虚拟机也有自己的内存模型,并且与硬件的缓存的访问操作比较类似。 二、Java内存模型 Java虚拟机中视图定义一种Java内存模型(Java Memory Model,JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果 注意,Java内存模型只要求上述两个操作必须按顺序执行,而没有保证是连续执行。 2.3 Java内存模型的三大特征 介绍完Java内存模型的相关操作和规则,我们再整体回顾一下这个模型的特征。
Java的世界也有属于它自己的内存模型,Java内存模型,即Java Memory Model,简称JMM。 由于Java被定义成一种跨平台的语言,所以在内存的描述上面也要能是跨平台的,Java虚拟机试图定义一种统一的内存模型,能将各种底层硬件及操作系统的内存访问差异进行封装,使Java程序在不同硬件及操作系统上都能达到相同的并发效果 Java内存模型具有三个特性:原子性、可见性和有序性。 可见性,在java内存模型中,简单说如果一条线程更改了共享变量的值,而其他线程能马上知道这个更改,我们则说这个变量具有可见性。 JMM可以说是Java的基础,它的定义将直接影响JVM及java多线程实现的机制,要想深入了解多线程并发中的相关问题现象,对Java内存模型的深入研究是必不可少的。
本文以及示例源码已归档在 javacore Java 内存模型(Java Memory Model),简称 JMM。 二、Java 内存模型 内存模型 这个概念。我们可以理解为:在特定的操作协议下,对特定的内存或高速缓存进行读写访问的过程抽象。不同架构的物理计算机可以有不一样的内存模型,JVM 也有自己的内存模型。 JVM 中试图定义一种 Java 内存模型(Java Memory Model, JMM)来屏蔽各种硬件和操作系统的内存访问差异,以实现让 Java 程序 在各种平台下都能达到一致的内存访问效果。 但 Java 内存模型只要求上述操作必须按顺序执行,而没有保证必须是连续执行。 三、Java 内存模型规则 内存交互操作的三大特性 上文介绍了 Java 内存交互的 8 种基本操作,它们遵循 Java 内存三大特性:原子性、可见性、有序性。
Java内存模型我们大致会分为两篇来讲,主要解决一下问题: 为什么需要并发处理 CPU高速缓存 缓存一致性 什么是内存模型 Java主内存和工作内存交互协议(原子性) Java内存模型-可见性 Java 内存模型-有序性 第6条和第7条我放在下一篇讲,话不多说,一起掀开Java高并发内容的第一章。 假设我们的WEB服务器同时有10个用户访问(每个响应大约需要1s),如果使用单线程,后面的9个用户则需要等待,如果一个用户很不幸是第10个,那么他将会需要等待10s以上,用户体验将会非常差。 什么是内存模型 内存模型可以理解为在特定的操作协议下,对特定内存或高速缓存进行读写访问的过程抽象。不同架构的物理机器拥有不一样的内存模型,而Java虚拟机也有自己的内存模型。 5. Java内存模型 Java虚拟机在工作时也有自己的主内存,每个线程有自己的工作内存,这就好比CPU高速缓存和物理机主内存一样,工作内存也是为了获得更好的执行速率。
java内存模型 happens-before 在JMM中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须要存在happens-before关系。 volatile写-读的内存语义 volatile写的内存语义:当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新到主内存。 volatile读的内存语义如下:当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量。 线程A写一个volatile变量,随后线程B读这个volatile变量,这个过程实质上是线程A通过主内存向线程B发送消息。 线程A释放锁,随后线程B获取这个锁,这个过程实质上是线程A通过主内存向线程B发送消息。
Java 内存模型的作用《Java虚拟机规范》中曾试图定义一种“Java内存模型”(Java Memory Model,JMM)来屏蔽各种硬件和操作系统的内存访问差异, 以实现让 Java 程序在各种平台下都能达到一致的内存访问效果 主内存 & 工作内存Java内存模型的主要目的是定义程序中各种变量的访问规则,即关注在虚拟机中把变量值存储到内存和从内存中取出变量值这样的底层细节。 注意, Java 内存模型只要求上述两个操作必须按顺序执行, 但不要求是连续执行。 先行发生原则先行发生原则(Happens-Before)是Java内存模型定义的一个等效判断原则。 参考资料《深入理解Java虚拟机》第 12 章:Java 内存模型与线程 12.3 Java 内存模型