Java虚拟机之内存模型
一.java并发基础
在并发编程中存在两个关键问题①线程之间如何通信 ②线程之间如何同步。
通信
通信是指线程之间以何种机制来交换信息。在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递。
在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信。
在消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过明确的发送消息来显式进行通信。
同步
同步是指程序用于控制不同线程之间操作发生相对顺序的机制。
在共享内存并发模型里,同步是显式进行的。程序员必须显式指定某个方法或某段代码需要在线程之间互斥访问。
在消息传递的并发模型里,由于消息的发送必须在消息的接收之前, 因此同步是隐式进行的。
Java并发采用的是共享内存模型,通信隐式进行;同步显示指定。
二.内存模型
Java内存模型JMM(Java Memory Model)主要目标是定义程序中各个变量(非线程私有)的访问规则,即在虚拟机中将变量存储到内存和从内存取出变量这样的底层细节。Java中每个线程都有自己私有的工作内存。工作内存保存了被该线程使用的变量的主内存副本拷贝,线程对变量的读写操作都必须在工作内存进行,无法直接读写主内存中的变量。两个线程无法直接访问对方的工作内存。
- 每一个线程有一个工作内存和主存独立
- 工作内存存放主存中变量的值的拷贝

(1)当数据从主内存复制到工作存储时,必须出现两个动作:第一,由主内存执行的读(read)操作;第二,由工作内存执行的相应的load操作;当数据从工作内存拷贝到主内存时,也出现两个操作:第一个,由工作内存执行的存储(store)操作;第二,由主内存执行的相应的写(write)操作。
(2) 每一个操作都是原子的,即执行期间不会被中断。
(3)对于普通变量,一个线程中更新的值,不能马上反应在其他变量中,如果需要在其他线程中立即可见,需要使用 volatile 关键字
内存模型的抽象:
在 Java 中,所有实例域、静态域 和数组元素存储在堆内存中,堆内存在线程之间共享。局部变量、方法定义参数 和 异常处理器参数 不会在线程之间共享,它们不会有内存可见性问题,也不受内存模型的影响。Java 线程之间的通信由 Java 内存模型(JMM)控制。JMM 决定了一个线程对共享变量的写入何时对另一个线程可见。从抽象的角度来看,JMM 定义了线程与主内存之间的抽象关系:线程之间的共享变量存储在主内存中,每一个线程都有一个自己私有的本地内存,本地内存中存储了该变量以读/写共享变量的副本。本地内存是 JMM 的一个抽象概念,并不真实存在。
JMM抽象示意图如下:

从上图来看,如果线程 A 和线程 B 要通信的话,要如下两个步骤:
1、线程 A 需要将本地内存 A 中的共享变量副本刷新到主内存去
2、线程 B 去主内存读取线程 A 之前已更新过的共享变量
步骤示意图:

举个例子:
本地内存 A 和 B 有主内存共享变量 X 的副本。假设一开始时,这三个内存中 X 的值都是 0。线程 A 正执行时,把更新后的 X 值(假设为 1)临时存放在自己的本地内存 A 中。当线程 A 和 B 需要通信时,线程 A 首先会把自己本地内存 A 中修改后的 X 值刷新到主内存去,此时主内存中的 X 值变为了 1。随后,线程 B 到主内存中读取线程 A 更新后的共享变量 X 的值,此时线程 B 的本地内存的 X 值也变成了 1。
整体来看,这两个步骤实质上是线程 A 再向线程 B 发送消息,而这个通信过程必须经过主内存。JMM 通过控制主内存与每个线程的本地内存之间的交互,来为 Java 程序员提供内存可见性保证。
内存间通信的指令:

Java虚拟机之内存模型的更多相关文章
- Java虚拟机:内存模型详解
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 我们都知道,当虚拟机执行Java代码的时候,首先要把字节码文件加载到内存,那么这些类的信息都存放在内存中的哪个区域呢?当我们创建一个对象实 ...
- java虚拟机的内存模型
一.为什么要了解java虚拟机的内存模型 java虚拟机作为java代码运行的平台,是java技术的基石.了解java虚拟机的内存模型也就变得十分必要.它能帮助我们更好的了解java代码的运行机制,更 ...
- Java虚拟机—Java8内存模型(整理版)
1.概述 对于Java程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要手动释放内存,不容易出现内存泄露和内存溢出问题.一旦出现内存泄露和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,排查错误 ...
- 深入理解JAVA虚拟机(内存模型+GC算法+JVM调优)
目录 1.Java虚拟机内存模型 1.1 程序计数器 1.2 Java虚拟机栈 局部变量 1.3 本地方法栈 1.4 Java堆 1.5 方法区(永久区.元空间) 附图 2.JVM内存分配参数 2.1 ...
- java虚拟机10.内存模型与线程
多任务处理在现代计算机操作系统中是一项必备的功能,让计算机同时去做几件事情,不仅是因为计算机的运算能力强大了,更重要的原因是计算机的运算速度与它的存储和通信子系统速度的差距太大,大量的时间都花费在磁盘 ...
- 如何写出让java虚拟机发生内存溢出异常OutOfMemoryError的代码
程序小白在写代码的过程中,经常会不经意间写出发生内存溢出异常的代码.很多时候这类异常如何产生的都傻傻弄不清楚,如果能故意写出让jvm发生内存溢出的代码,有时候看来也并非一件容易的事.最近通过学习< ...
- java虚拟机的内存机制
我们都知道,java程序的跨平台性离不开java虚拟机,虚拟机隔绝了底层操作系统,使得java程序可以直接运行在虚拟机之上.所以,对java的学习,离不开对java虚拟机的学习与了解.下面简单整理下j ...
- 关于JAVA中的static方法、并发问题以及JAVA运行时内存模型
一.前言 最近在工作上用到了一个静态方法,跟同事交流的时候,被一个问题给问倒了,只怪基础不扎实... 问题大致是这样的,“在多线程环境下,静态方法中的局部变量会不会被其它线程给污染掉?”: 我当时的想 ...
- 从Java虚拟机的内存区域、垃圾收集器及内存分配原则谈Java的内存回收机制
一.引言: 在Java中我们只需要轻轻地new一下,就可以为实例化一个类,并分配对应的内存空间,而后似乎我们也可以不用去管它,Java自带垃圾回收器,到了对象死亡的时候垃圾回收器就会将死亡对象的内存回 ...
随机推荐
- Django 3.0中不推荐使用的及已经删除的功能
3.0中不推荐使用的功能 django.utils.encoding.force_text()和smart_text()的别名被弃用.如果您的代码支持Python 2,smart_str()并且 fo ...
- LINQ---查询变量
LINQ查询可以返回两种类型的结果----枚举和标量(scalar)的单一值 namespace ConsoleApplication46 { class Program { static void ...
- 个人项目发表到GitHub
个人项目源程序代码发送到github上. 因为之前假期已经注册过了账户,所以只是上传了做过的小账本项目. https://www.cnblogs.com/sdcs/p/8270029.html
- swoole之建立 tcp server
一.swoole的安装 参照官网:https://wiki.swoole.com/wiki/page/6.html 二.代码部分 服务端: <?php $host = "127.0.0 ...
- 用 k8s 运行一次性任务【转】
容器按照持续运行的时间可分为两类:服务类容器和工作类容器. 服务类容器通常持续提供服务,需要一直运行,比如 http server,daemon 等.工作类容器则是一次性任务,比如批处理程序,完成后容 ...
- JS浮点数的研究
为什么0.1 + 0.2 得到的是 0.30000000000000004 console.log( 0.1 + 0.2 == 0.3);//false 在js中所有的整数和小数都是以Number形式 ...
- [题解] LuoguP4091 [HEOI2016/TJOI2016]求和
传送门 首先我们来看一下怎么求\(S(m,n)\). 注意到第二类斯特林数的组合意义就是将\(m\)个不同的物品放到\(n\)个没有区别的盒子里,不允许有空盒子的方案数. 那么将\(m\)个不同的物品 ...
- 软件管理-RPM命令管理:安装升级与卸载
1.包名与包全名 包名 : 操作已经安装的软件包时,使用包名:系统会搜索var/lib/rpm中的数据库 包全名: 操作的包时没有安装的软件包时,使用包全名,而且注意路径 2.RPM安装 切换到光盘p ...
- HDU - 6152 Friend-Graph(暴力)
题意:给定n个人的关系,若存在三个及以上的人两两友好或两两不友好,则"Bad Team!",否则"Great Team!". 分析:3000*3000内存100 ...
- 被疯狂吐槽的iPhoneXR屏幕真如传言中的那么差吗?
在双十一期间,最受果粉关注的电商平台不是天猫,也不是京东,而是拼多多!原因很简单,拼多多疯狂给出iPhone的各种超低价格,直接压制了竞争对手.以iPhone XR为例,依据容量不同,价格分别为558 ...