从多核硬件架构,看Java内存模型

在了解Java内存模型之前,先来看一下多核硬件架构。

我们应该都知道,计算机在执行程序的时候,每条指令都是在CPU中执行的,而执行的时候,又免不了要和数据打交道。而计算机上面的数据,是存放在主存当中的,也就是计算机的物理内存啦。

刚开始,还相安无事的,但是随着CPU技术的发展,CPU的执行速度越来越快。而由于内存的技术并没有太大的变化,所以从内存中读取和写入数据的过程和CPU的执行速度比起来差距就会越来越大,这就导致CPU每次操作内存都要耗费很多等待时间。

所以,人们想出来了一个好的办法,就是在CPU和内存之间增加高速缓存。缓存的概念大家都知道,就是保存一份数据拷贝。他的特点是速度快,内存小,并且昂贵。

再随着市场对CPU计算能力的需要,于是出现了多核CPU,每个核都有各自的缓存。下图简单描述了多核硬件架构的实现。

img_d9f74ea1eb2b66ccfb196cbc28cb45e4.png

现代计算机硬件,几乎都是多核处理器实现。打开Windows的任务管理器,可以核心数,还可以看到处理器的缓存。如下图红框:

img_a9d6ba649dc71e1f4eaaf0351fe9e9c6.png

可以清晰的看到L1、L2、L3三级缓存。

计算机内部的缓存架构(CPU三级缓存)
img_10f4b9914b51ffd28bd766dc2acf6c8d.png

缓存大大缩小了高速CPU与低速内存之间的差距。以三层缓存架构为例:

  • L1 Cache最接近CPU, 容量最小(如32K、64K、256K等)、速度最高,每个核上都有一个L1 Cache。
  • L2 Cache容量更大(如256K)、速度更低, 一般情况下,每个核上都有一个独立的L2 Cache。
  • L3 Cache最接近内存,容量最大(如12MB),速度最低,在同一个CPU插槽之间的核共享一个L3 Cache。

单核时代只有一个处理器核心,读/写操作完全都是由单核完成,没什么问题;但是多核架构,一个核修改主存后,其他核心并不知道数据已经失效,继续傻傻的使用,轻则数据计算错误,重则导致死循环、程序崩溃等。

缓存一致性协议

多核CPU硬件架构厂商,设计之初就预测到多线程操作数据不一致的问题,因此出现了——缓存一致性协议。

不同的CPU硬件生产厂商,具体的实现不一样。Intel的MESI协议最出名。
MESI协议文档:https://en.wikipedia.org/wiki/MESI_protocol

在MESI协议中,每个Cache line有4个状态,可用2个bit表示,它们分别是:

状态描述
M(Modified)这行数据有效,数据被修改了,和内存中的数据不一致,数据只存在于本Cache中。
E(Exclusive)这行数据有效,数据和内存中的数据一致,数据只存在于本Cache中。
S(Shared)这行数据有效,数据和内存中的数据一致,数据存在于很多Cache中。
I(Invalid)这行数据无效。

在MESI协议中,每个Cache的Cache控制器不仅知道自己的读写操作,而且也监听(snoop)其它Cache的读写操作。每个Cache line所处的状态根据本核和其它核的读写操作在4个状态间进行迁移,如下图:

img_879ead2d86249b6cc42a968671107002.png

AMD的Opteron处理器使用从MESI中演化出的MOESI协议,O(Owned)是MESI中S和M的一个合体,表示本Cache line被修改,和内存中的数据不一致,不过其它的核可以有这份数据的拷贝,状态为S。

Intel的core i7处理器使用从MESI中演化出的MESIF协议,F(Forward)从Share中演化而来,一个Cache line如果是Forward状态,它可以把数据直接传给其它内核的Cache,而Share则不能。

用下面的简图,简单说明下MESI如何在多核环境,确保缓存一致性的。
img_588b3cebdda667288a517efa9d5b31cd.png

两个CPU执行两个线程,都执行count++,都先从主内存获取count=0,都将count=0从主存拷贝到各自的缓存区,且在缓存区count=0的状态为S(Shared,多线程共享状态)。

一个线程(左边的线程)先执行了修改count+=1,按MESI缓存协议规范,在该线程中count是M状态(即:已被修改),则其他拥有count变量的线程,count状态都变为(I)失效状态,即需要再去主内存拿新值。

可见,缓存一致性协议解决了多核硬件架构的一致性问题。那缓存一致性又和JMM有什么关系呢?

JMM也是遵照多核硬件架构的设计,用Java实现了一套JVM层面的“缓存一致性”。
如果开发者运用的得当,最终可以达到Java线程间:变量可见性、有序性、原子性。

有了MESI,为什么还需要JMM?

既然有了MESI协议,是不是就不需要volatile的可见性语义了?当然不是,还有以下问题:

  • 并不是所有的硬件架构都提供了相同的一致性保证,不同的硬件厂商实现不同,JVM需要volatile统一语义。
  • 可见性问题不仅仅局限于CPU缓存内,JVM自己维护的内存模型(JMM)中也有可见性问题。使用volatile做标记,可以解决JVM层面的可见性问题。

Java内存模型JMM

Java内存模型(Java Memory Model,简称JMM),本身是种抽象的概念,并不是像硬件架构一样真实存在的;它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段、静态字段和构成数组对象的元素)的访问方式。

由于JVM运行程序的实体是线程,而每个线程创建时,JVM都会为其创建一个工作内存(有些地方称为栈空间),用于存储线程私有数据,而Java内存模型中规定所有变量都存储在主内存,主内存时关系内存区域,所有线程都可以访问,但线程对变量的操作(读取赋值等)必须在工作内存中进行,首先要将变量从主内存拷贝到自己的工作内存空间,然后对变量进行操作,操作完后再将变量写回主内存,不能直接操作主内存中的变量。

工作内存是每个线程的私有数据区域,因此不同线程间无法访问对方的工作内存,线程间的通信(传值)必须通过主内存来完成。如下图所示:

img_a59bb77dd96048e8c9cfa9ece006bbf5.png
内存模型JMM与Java运行时数据区的关系

Java虚拟机的运行时数据区被划分为:方法区、Java堆、Java虚拟机栈、PC寄存器、本地方法栈,还有常量池。它们被分为两大类——线程共享和线程私有数据区。

线程共享数据区,包括:Java堆、方法区、常量池。它们会随着虚拟机启动而创建,随着虚拟机退出而销毁。

线程私有数据区,包括:PC寄存器、JVM栈、本地方法区。它们是与线程一一对应的,这些与线程对应的数据区域会随着线程开始和结束而创建和销毁。详细了解可阅读:JVM体系结构-----深入理解内存结构

本质上来说,内存模型JMM和Java运行时数据区没有任何关系,它们是两个不同纬度的东西。

但如果硬要扯上关系的话,可以把Java运行时数据区的JVM栈 看作是内存模型中的"工作内存",因为按Java运行时数据区对内存的划分,符合线程私有性质、且存储本地变量的存储区域,只有线程私有的栈空间。

JMM主内存与工作内存的数据存储类型以及操作方式

根据虚拟机规范,对于一个实例对象中的成员方法而言

1、如果方法中包含本地变量是基本数据类型,将直接存储在工作内存(栈)中;

2、但如果本地变量是引用类型,那么该变量的引用会存储在工作内存的栈中,而对象的实例将存储在主内存(堆)中。但对于实例对象的成员变量,不管它是基本数据类型或者包装类型(Integer、Double等)还是引用类型,都会被存储到堆区。

3、至于static变量以及类自身相关信息将会存储在主内存中。

需要注意的是,在主内存中的实例对象可以被多线程共享,如果两个线程同时调用了同一个对象的同一个方法,那么两个线程会将 要操作的数据拷贝一份到自己的工作内存中,执行完成后才刷新到主内存,如下图所示:

img_0e36de45d660639884475409e28247ef.png
Java内存模型 与 硬件内存架构的关系

对于硬件架构来说,只有寄存器、缓存、主内存的概念,并没有工作内存(线程私有数据区)和主内存(堆内存)之分,也就是说Java内存模型对内存的划分对硬件内存并没有任何影响,因为JMM是一种抽象的概念,是一组规则,并不实际存在,不管是工作内存的数据还是主内存的数据,对于计算机硬件来说都会存储在计算机主内存中,当然也有可能存储到CPU缓存或者寄存器中,因此总体上,Java内存模型和硬件内存架构师一个相互交叉的关系,是一种抽象概念划分与真实物理硬件的交叉。(注意对于Java内存区域划分也是同样的道理)

img_2cc124b280a11709f1a962d5e548c5a3.png
小结:

1、硬件架构的缓存一致性协议(如MESI),解决了多核硬件的一致性问题。
JMM也是遵照多核硬件架构的设计,用Java实现了一套JVM层面的“缓存一致性”。
如果开发者运用的得当,最终可以达到Java线程间:内存可见性、有序性、原子性。
2、JMM不像硬件架构,不是实实在在存在的,JMM是理论基础。但JMM最终还是要落到硬件架构上去运行。


存档文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 汽车电子咖啡厅多核AUTOSAR架构开发是近年来汽车电子技术的一项重要应用,在汽车电子领域得到了广泛的关注和应用。汽车电子咖啡厅是基于多核AUTOSAR架构开发的一款新型车载咖啡机,它不仅保证了汽车的行驶安全,还能够在车内提供咖啡冲泡服务,为驾驶员和乘客提供舒适和便利。在多核AUTOSAR架构的设计中,智能化控制系统是其中的重点部分,它将咖啡机的控制和监测功能完美的整合到了汽车电子系统中。 在多核AUTOSAR架构的应用过程中,针对咖啡机控制和监测功能的应用需求,需要对咖啡机进行嵌入式开发和各种信号传递功能的调试和测试,以确保咖啡机的性能稳定和可靠。咖啡机的控制模块需要通过CAN总线与汽车电子系统中的其他模块实现交互,各模块之间的通讯方式采用了多核AUTOSAR架构标准中的PDU数据格式,使得咖啡机的控制和监测功能能够兼容其他汽车电子部件。 总的来说,汽车电子咖啡厅多核AUTOSAR架构的应用将汽车电子技术与生活应用紧密结合,为人们提供了更加舒适便捷的驾乘体验和娱乐享受,并且也进一步促进了汽车电子技术的飞速发展。 ### 回答2: 汽车电子咖啡厅是指将现有的咖啡厅店面与汽车电子技术相结合的一种新型商业模式。该模式可以为顾客提供更加舒适、智能和优质的用餐体验,同时也可以为企业提供更好的商业发展机会。 在这个模式中,汽车电子技术的应用相当重要,而多核autosar架构的开发则是其中的关键技术之一。多核autosar架构是一种将多个处理器核心结合起来工作的架构,它可以提高系统的可靠性和性能,并且可以更好地支持复杂的多任务应用。 在汽车电子咖啡厅中,多核autosar架构可以应用于多个场景和功能。例如,它可以用于智能点餐系统、自动化餐品准备系统、环境监测设备、智能支付系统等方面。通过多核autosar架构的支持,这些系统可以更好地实现高效、智能、可靠的运作。 除了多核autosar架构,汽车电子咖啡厅还需要其他的关键技术支持,例如人机交互技术、物联网技术、智能终端设备等。这些技术的结合可以实现更加完善的汽车电子咖啡厅模式,为顾客和企业带来更大的收益和利益。 ### 回答3: 汽车电子咖啡厅是一种新兴的智能化咖啡厅,它拥有多种功能,包括提供咖啡、提供Wi-Fi、提供一系列娱乐和信息服务等。在汽车电子咖啡厅的开发中,使用了多核autosar架构,这是一种新型的汽车电子软件架构,它具有高度的可扩展性和可复用性。 多核autosar架构的开发主要包括三个方面:系统设计、软件设计和硬件设计。在系统设计方面,开发人员需要根据系统需求进行分析和设计,并确定系统的硬件和软件组件。在软件设计方面,开发人员需要根据系统需求设计软件组件,并确定程序的技术实现方法。在硬件设计方面,开发人员需要根据系统需求设计硬件组件,并确定系统的实现方式。 多核autosar架构的开发过程需要尽可能地提高开发效率、软件可靠性和安全性,同时还要满足汽车电子系统对实时处理的要求。因此,在开发过程中,需要使用高效的开发工具和技术,并对软件的实现过程进行严格的测试和验证,确保系统的稳定性和可靠性,进而推动汽车电子咖啡厅这些新兴设施的发展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值