全面理解Java内存模型

  • 时间:
  • 浏览:9
  • 来源:神彩IOS下载_彩神IOS下载官方

在并发编程领域,有另一个 关键问提:守护系统进程之间的通信同步

在共享内存并发模型里,同步是显式进行的。守护系统进程员前要显式指定某个妙招 或某段代码前要在守护系统进程之间互斥执行。

如上图所示,本地内存A和B有主内存中共享变量x的副本。假设初始时,太少个 内存中的x值都为0。守护系统进程A在执行时,把更新后的x值(假设值为1)临时存放进去去太少人的本地内存A中。当守护系统进程A和守护系统进程B前要通信时,守护系统进程A首先会把太少人本地内存中修改后的x值刷新到主内存中,此时主内存中的x值变为了1。就让,守护系统进程B到主内存中去读取守护系统进程A更新后的x值,此时守护系统进程B的本地内存的x值也变为了1。

堆区含有了Java应用创建的所有对象信息,不管对象是哪个守护系统进程创建的,其中的对象包括原始类型的封装类(如Byte、Integer、Long等等)。不管对象是属于另一个 成员变量还是妙招 中的本地变量,它一定会被存储在堆区。

从上图来看,守护系统进程A与守护系统进程B之间如要通信一句话,前要要经历下面另一个 步骤:

不可能 太少人要想深入了解Java并发编程,就要先理解好Java内存模型。Java内存模型定义了多守护系统进程之间共享变量的可见性以及怎样才能在前要的就让对共享变量进行同步。原始的Java内存模型波特率并就有很理想,可是Java1.5版本对其进行了重构,现在的Java8仍沿用了Java1.5的版本。

不管为什么会么会会么会重排序,单守护系统进程下的执行结果必须被改变,编译器、runtime和解决器都前要遵守as-if-serial语义。

当多个守护系统进程一块儿操作同另一个 共享对象时,不可能 如此合理的使用volatile和synchronization关键字,另一个 守护系统进程对共享对象的更新有不可能 由于分析其它守护系统进程不可见。

不可能 另一个 变量是volatile修饰的,JMM会在写入太少字段就让放进去去另一个 Write-Barrier指令,并在读太少字段就让插入另一个 Read-Barrier指令。这由于分析分析,不可能 写入另一个 volatile变量,就还前要保证:

从jdk5开始英文,java使用新的JSR-133内存模型,基于happens-before的概念来阐述操作之间的内存可见性。

Memory Barrier所做的另外一件事是强制刷出各种CPU cache,如另一个 Write-Barrier(写入屏障)将刷出所有在Barrier就让写入 cache 的数据,可是,任何CPU上的守护系统进程都能读取到那些数据的最新版本。

Java内存模型即Java Memory Model,简称JMM。JMM定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作妙招 。JVM是整个计算机虚拟模型,太少JMM是隶属于JVM的。

里边讲到了,通过内存屏障还前要禁止特定类型解决器的重排序,从而让守护系统进程按太少人预想的流程去执行。内存屏障,又称内存栅栏,是另一个 CPU指令,基本上它是一条如此 的指令:

不可能 多个守护系统进程共享另一个 对象,不可能 它们一块儿修改太少共享对象,这就产生了竞争问提。

关于Java守护系统进程之间的通信,还前要参考守护系统进程之间的通信(thread signal)。

注意:另一个 操作之间具有happens-before关系,太少由于分析分析前另一个 操作前要要在后另一个 操作就让执行!仅仅要求前另一个 操作的执行结果,对于后另一个 操作是可见的,且前另一个 操作按顺序排在后另一个 操作就让。

所有原始类型(boolean,byte,short,char,int,long,float,double)的本地变量都直接保处于守护系统进程栈当中,对于它们的值各个守护系统进程之间就有独立的。对于原始类型的本地变量,另一个 守护系统进程还前要传递另一个 副本给如此 守护系统进程,当它们之间是无法共享的。

从整体来看,太少个 步骤实质上是守护系统进程A在向守护系统进程B发送消息,可是太少通信过程前要要经过主内存。JMM通过控制主内存与每个守护系统进程的本地内存之间的交互,来为java守护系统进程员提供内存可见性保证。

要解决里边的问提太少人还前要使用java synchronized代码块。synchronized代码块还前要保证同另一个 时刻必须有另一个 守护系统进程进入代码竞争区,synchronized代码块不利于保证代码块中所有变量就有可能 从主存中读,当守护系统进程退出代码块时,对所有变量的更新不可能 flush到主存,不管那些变量是就有volatile类型的。

下图展示了里边描述的过程:

当另一个 CPU前要访问主存时,会先读取一次要主存数据到CPU缓存,进而在读取CPU缓存到寄存器。当CPU前要写数据到主存时,同样会先flush寄存器到CPU缓存,可是再在太少节点把缓存数据flush到主存。

想象一下太少人的共享对象存储在主存,另一个 CPU中的守护系统进程读取主存数据到CPU缓存,可是对共享对象做了更改,但CPU缓存中的更改后的对象还如此flush到主存,此时守护系统进程对共享对象的更改对其它CPU中的守护系统进程是不可见的。最终太少每个守护系统进程最终一定会拷贝共享对象,可是拷贝的对象处于不同的CPU缓存中。

下图展示了里边描述的过程。左边CPU中运行的守护系统进程从主存中拷贝共享对象obj到它的CPU缓存,把对象obj的count变量改为2。但太少变更对运行在右边CPU中的守护系统进程不可见,不可能 太少更改还如此flush到主存中:



要解决共享对象可见性太少问提,太少人还前要使用java volatile关键字。 Java’s volatile keyword. volatile 关键字还前要保证变量会直接从主存读取,而对变量的更新也会直接写到主存。volatile原理是基于CPU内存屏障指令实现的,里边会讲到。

在执行守护系统进程时,为了提高性能,编译器和解决器会对指令做重排序。可是,JMM确保在不同的编译器和不同的解决器平台之上,通过插入特定类型的Memory Barrier来禁止特定类型的编译器重排序和解决器重排序,为上层提供一致的内存可见性保证。

里边也说到了,Java内存模型太少另一个 抽象概念,如此它在Java中具体是为什么会么会会么会工作的呢?为了更好的理解上Java内存模型工作妙招 ,下面就JVM对Java内存模型的实现、硬件内存模型及它们之间的桥接做删改介绍。

下面通过示意图来说明太少个 步骤:

不可能 另一个 操作访问同另一个 变量,其中另一个 为写操作,此时太少个 操作之间处于数据依赖性。

编译器和解决器太少再改变处于数据依赖性关系的另一个 操作的执行顺序,即太少再重排序。

编译器和CPU不利于重排序指令,保证最终相同的结果,尝试优化性能。插入一条Memory Barrier会告诉编译器和CPU:不管那些指令就有能和这条Memory Barrier指令重排序。

如下图所示,守护系统进程A和守护系统进程B共享另一个 对象obj。假设守护系统进程A从主存读取Obj.count变量到太少人的CPU缓存,一块儿,守护系统进程B也读取了Obj.count变量到它的CPU缓存,可是太少个 守护系统进程都对Obj.count做了加1操作。此时,Obj.count加1操作被执行了两次,不过就有不同的CPU缓存中。

这和java有那些关系?里边java内存模型中讲到的volatile是基于Memory Barrier实现的。

守护系统进程的通信是指守护系统进程之间以何种机制来交换信息。在命令式编程中,守护系统进程之间的通信机制有两种 共享内存消息传递

在消息传递的并发模型里,不可能 消息的发送前要在消息的接收就让,可是同步是隐式进行的。

里边讲到了Java守护系统进程之间的通信采用的是过共享内存模型,这里提到的共享内存模型指的太少Java内存模型(简称JMM),JMM决定另一个 守护系统进程对共享变量的写入好久对如此 守护系统进程可见。从抽象的深度图来看,JMM定义了守护系统进程和主内存之间的抽象关系:守护系统进程之间的共享变量存储在主内存(main memory)中,每个守护系统进程就有另一个 私有的本地内存(local memory),本地内存中存储了该守护系统进程以读/写共享变量的副本。本地内存是JMM的另一个 抽象概念,太少真实处于。它含有了缓存,写缓冲区,寄存器以及太少的硬件和编译器优化。

消息传递的并发模型里,守护系统进程之间如此公共情况表,守护系统进程之间前要通过明确的发送消息来显式进行通信,在java中典型的消息传递妙招 太少wait()notify()

在JMM中,不可能 另一个 操作的执行结果前要对如此 操作可见,如此太少个 操作之间前要要处于happens-before关系,太少的另一个 操作既还前要在同另一个 守护系统进程,也还前要在不同的另一个 守护系统进程中。

参考文档 :

1. http://www.infoq.com/cn/articles/java-memory-model-1

2. http://www.jianshu.com/p/d3fda02d4cae

下图展示了调用栈和本地变量都存储在栈区,对象都存储在堆区:



另一个 本地变量不可能 是原始类型,如此它会被删改存储到栈区。

另一个 本地变量就有不可能 是另一个 对象的引用,太少情况表下,太少本地引用会被存储到栈中,可是对象两种 仍然存储在堆区。

现代计算机一般就有另一个 以上CPU,可是每个CPU还有不可能 含有多个核心。可是,不可能 太少人的应用是多守护系统进程一句话,那些守护系统进程不可能 会在各个CPU核心中并行运行。

正如里边讲到的,Java内存模型和硬件内存架构太少一致。硬件内存架构中并如此区分栈和堆,从硬件上看,不管是栈还是堆,大次要数据一定会存到主存中,当然一次要栈和堆的数据就有不可能 会存到CPU寄存器中,如下图所示,Java内存模型和计算机硬件内存架构是另一个 交叉关系:



当对象和变量存储到计算机的各个内存区域时,必然会面临太少问提,其中最主要的另一个 问提是:

堆中的对象还前要被多守护系统进程共享。不可能 另一个 守护系统进程获得另一个 对象的应用,它便可访问太少对象的成员变量。不可能 另一个 守护系统进程一块儿调用了同另一个 对象的同另一个 妙招 ,如此太少个 守护系统进程便可一块儿访问太少对象的成员变量,可是对于本地变量,每个守护系统进程一定会拷贝一份到太少人的守护系统进程栈中。

守护系统进程栈还含有了当前妙招 的所有本地变量信息。另一个 守护系统进程必须读取太少人的守护系统进程栈,也太少说,守护系统进程中的本地变量对其它守护系统进程是不可见的。即使另一个 守护系统进程执行的是同一段代码,它们也会个人所有在太少人的守护系统进程栈中创建本地变量,可是,每个守护系统进程中的本地变量一定会有太少人的版本。

删改请见 volatile和synchronized的区别

不管是那些内存模型,最终还是运行在计算机硬件上的,太少人有必要了解计算机硬件内存架构,下图就简单描述了当代计算机硬件内存架构:

Java守护系统进程之间的通信突然隐式进行,整个通信过程对守护系统进程员删改透明。不可能 编写多守护系统进程守护系统进程的Java守护系统进程员不理解隐式进行的守护系统进程之间通信的工作机制,很不可能 会遇到各种奇怪的内存可见性问提。

与守护系统进程员密切相关的happens-before规则如下:

Static类型的变量以及类两种 相关信息一定会随着类两种 存储在堆区。

共享内存的并发模型里,守护系统进程之间共享守护系统进程的公共情况表,守护系统进程之间通过写-读内存中的公共情况表来隐式进行通信,典型的共享内存通信妙招 太少通过共享对象进行通信。

对于另一个 对象的成员妙招 ,那些妙招 含有有本地变量,仍前要存储在栈区,即使它们所属的对象在堆区。

对于另一个 对象的成员变量,不管它是原始类型还是包装类型,一定会被存储到堆区。

不可能 太少个 加1操作是串行执行的,如此Obj.count变量便会在原始值加在2,最终主存中的Obj.count的值会是3。然而下图中另一个 加1操作是并行的,不管是守护系统进程A还是守护系统进程B先flush计算结果到主存,最终主存中的Obj.count只会增加1次变成2,尽管一共有两次加1操作。

同步是指守护系统进程用于控制不同守护系统进程之间操作处于相对顺序的机制。

在JVM实物,Java内存模型把内存分成了两次要:守护系统进程栈区和堆区,下图展示了Java内存模型在JVM中的逻辑视图:



JVM中运行的每个守护系统进程都拥有太少人的守护系统进程栈,守护系统进程栈含有了当前守护系统进程执行的妙招 调用相关信息,太少人也把它称作调用栈。随着代码的不断执行,调用栈会不断变化。

在CPU实物有一组CPU寄存器,也太少CPU的储存器。CPU操作寄存器的波特率要比操作计算机主存快的多。在主存和CPU寄存器之间还处于另一个 CPU缓存,CPU操作CPU缓存的波特率快于主存但慢于CPU寄存器。太少CPU不可能 有多个缓存层(一级缓存和二级缓存)。计算机的主存也称作RAM,所有的CPU都不利于访问主存,可是主存比里边提到的缓存和寄存器大太少。

猜你喜欢

1500元左右的手机,好用。性价比高。推荐一下吧。谢谢

下载百度知道APP,抢鲜体验你对你这俩 回答的评价是?展开完整版你对你这俩 回答的评价是?展开完整版本回答由提问者推荐怪怪的推荐魅蓝e华为和小米。上官网去看看,总有一款一款

2020-03-22

赵老师,您好,不知道你们是怎么对这些表做读写比例分析的(不改源码/改源码)?

0人评论发布于2016-04-1520:36:192016-04-1520:31:18Ali_冷香zhenzhongpan0人评论1377人浏览0收藏来源:[直播]0人评论发布

2020-03-22

推荐个性价比高的智能手机,1000到3000的.最好亲自试验过。

华为nova4不错的,全网通6GB+128GB版本华为商城官网在售价为2499元,手机参数如下:1、屏幕:屏幕尺寸为6.4英寸,屏幕色彩为1670万色,分辨率为FHD+2310

2020-03-22

AI·重构企业客户服务能力

用于实时预测用户对物品偏好,支持企业定制推荐算法,支持A/BTest效果对比深度1挖掘企业与企业、企业与人物的关系,通很多 位交叉分析及智能算法,构建基于企业全息画像和企业关

2020-03-21

想买部手机,现在什么手机好

4、电池:电池容量为1000mAh(典型值),标配充电器支持4.5V/5A或5V/4.5A或5V/2A输出,兼容9V/2A快充,理论充电时间约1.5小时,续航更持久。3、性能:

2020-03-21