思考:Java内存模型和硬件内存模型

news2024/12/25 1:36:42

前言

前一阵在看volatile的原理,看到内存屏障和缓存一致性,发现再往底层挖就挖到了硬件和Java内存模型。这一块是自己似懂非懂的知识区,我一般称之为知识混沌区。因此整理这一篇文章。

什么是内存模型(Memory Model)呢?它是系统和程序员之间的规范,它规定了存储器访问的行为,并影响到了性能。并且,Memory Model有多层,处理器规定、编译器规定、高级语。对于高级语言来说,如Java内存模型, 它通常需要支持跨平台,也就是说它会基于各种不同的内存模型,但是又要提供给程序员一个统一的内存模型,可以理解为一个适配器的角色。

这篇文字主要包含了三部分:

  1. 硬件内存模型

  2. Java内存模型和运行时数据区

  3. 三者的关系

硬件内存模型

下图是2012 Sandy Bridge(一种Intel处理器)核心设计。图中有socket1和socket2,可以理解为了这台电脑中有两个插cpu的槽,每个槽中有一个多核(C1,C2...Cn)的cpu。对于CPU的内存模型可以大致按照如下进行分解:

寄存器

编译器会将本地变量和函数参数分配到这些寄存器上

内存排序缓冲(Memory Ordering Buffers)

这些缓冲用于记录等待缓存子系统时正在执行的操作

L1 缓存

空间最小,访问速度最快

L2缓存

要作用是作为L1和L3之间的高效内存访问队列。L2缓存同时包含数据和指令

L3缓存

在同插槽的所有核心都共享L3缓存。

主内存

在缓存完全没命中的情况下

简化之后如下图所示,计算机在高速的 CPU 和相对低速的存储设备(内存,RAM)之间使用高速缓存,作为内存和处理器之间的缓冲。将运算需要使用到的数据复制到缓存中,让运算能快速运行,当运算结束后再从缓存同步回内存之中。

在多处理器的系统中(或者单处理器多核的系统),每个处理器内核都有自己的高速缓存,它们有共享同一主内存(Main Memory---RAM)。

Java内存模型和运行时数据区

说完系统的内存模型,然后开始说一下Java的内存模型(Java Memory Model,简称 JMM)。

    

Java语言一大特性就是跨平台型。其背后的实现便是在Java 虚拟机规范中定义的Java 内存模型(Java Memory Model,简称 JMM)。

虚拟机通过内存模型,定义了将变量存储到内存和从内存中取出变量的底层细节(字节码指令转换是另一方面),屏蔽掉各种硬件和操作系统的内存访问差异,实现让 Java 程序在各种平台下都能达到一致的内存访问效果,不必因为不同平台上的物理机的内存模型的差异,对各平台定制化开发程序。

上面提到了两个重要的概念--内存和变量。

先说内存,Java内存模型中的内存分为两类:主内存(Main Memory)和工作内存(Working Memory,又称本地内存)。其详情如下:

主内存可以类比成物理硬件的主内存,但此处仅是虚拟机内存的部分。工作内存可以类比成处理器高速缓存

主内存是所有的线程共享,每个线程都有自己的工作内存,属于线程私有。

一个线程不能访问另一个线程的工作内存,线程之间需要通过主内存来实现线程间的通信;

线程的工作内存中保存了该线程使用到的变量的主内存副本拷贝,线程对变量的所有的操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存的变量;

如果想理解上面提到的变量(Variables)的提取和存储。那就需要继续看一下JVM另一个重要的知识点--运行时数据区。如下图所示,不同jdk版本的运行时数据区划分有所差异。但主要分为了五部分:方法区(8开始使用元数据),堆,栈,程序计数器,本地方法栈。细节就不展开讲。

内存模型中管理的变量(Variables)则主要指是堆中的数据,它包括了实例字段、静态字段和构成数值对象的元素,如数组等。但不包括Java方法中局部变量与方法参数,如果局部变量是一个 reference 类型,它引用的对象在 Java 堆中可被各个线程共享,但是 reference 本身在 Java 栈的局部变量表中。

总结一下:Java 运行时数据区和内存模型是不一样的东西,更确切的说应该是不是同一层次的东西。

  1. 内存模型:是定义了线程和主内存之间的抽象关系,更多的是定义规则

  2. 运行时数据区域:是指 JVM 运行时将数据分区域存储,强调对内存空间的划分。

硬件内存模型和Java内存模型关系

Java内存模型中的主内存和工作内存的区别在于线程调度和共享的区别,而不是物理层面的区别。因此硬是将Java内存模型和硬件内存模型进行映射没有意义。如果真的有关系,只能说工作内存更多的是CPU寄存器和缓存。当然,工作内存由于上下文切换等原因,也可能会写回RAM(可以理解为物理内存,严谨来说是物理虚拟内存)。

对于运行时数据区而言,有些是随着虚拟机启动而创建,虚拟机关闭而销毁。还有一部分是随着线程生命周期创建销毁的。

线程间共享的方法区和堆,是说它们会随着虚拟机启动而创建,随着虚拟机退出而销毁。而栈和程序计数器会随着线程开始和结束而创建和销毁。

正如下图所示,方法区和堆在RAM中,也可以在缓存中,这也是JVM创建时进行管理的内存空间。

以堆为例,由于对象实例的创建在JVM中非常频繁,一方面保证并发环境下从堆区中划分内存空间的线程安全,另一方面提升内存分配的吞吐量。对Eden区域继续进行划分,JVM为每个线程分配一个私有缓存区域--本地线程分配缓冲((Thread Local Allocation Buffer,TLAB)。而这个缓冲则缓存中,而不是RAM中

如前所述,Java内存模型和硬件内存架构是不同的。 线程栈和堆的一部分有时可能存在于CPU高速缓存和内部CPU寄存器中。 

参考资料:

https://jenkov.com/tutorials/java-concurrency/java-memory-model.html

指令重排序 - 简书

https://www.cnblogs.com/czwbig/p/11127124.html

https://zhuanlan.zhihu.com/p/51613784

Java 运行时数据区和内存模型(JMM)_jmm 和运行时数据区 的关系看-CSDN博客

简单介绍一下什么是“工作内存”和“主内存”(JMM中的概念)_工作内存和主内存-CSDN博客

JVM运行时数据区------堆_数据区和堆-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1912940.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

46、lvs集群- 博客

1、lvs集群: lvs:linux virtual server----章文嵩发起的开源项目,阿里。linux的内核层面实现负载均衡的软件。 主要作用:将多个后端服务器组成一个高可用,高性能的服务器集群,通过负载均衡的算法将客户端的…

前端javascript中的排序算法之插入排序

插入排序(Selection Sort)基本思想: 插入排序每次排一个数组项,以此方式构建最后的排序数组。假定第一项已经排序了,接着, 它和第二项进行比较,第二项是应该待在原位还是插到第一项之前呢&#…

查看oracle ojdbc所支持的JDBC驱动版本

oracle jcbc驱动的下载地址参考:JDBC and UCP Downloads page 其实上文中对ojdbc所支持的JDBC驱动版本已经有说明了,不过,因为oracle的驱动包很多时间,都是在公司内部私服里上传维护的,上传的时候,可能又没…

第4章 课程发布:模块需求分析,课程预览(模板引擎 静态页面),课程审核,课程发布(分布式事务,页面静态化:熔断降级),课程搜索(es索引)

1 模块需求分析 1.1 模块介绍 课程信息编辑完毕即可发布课程,发布课程相当于一个确认操作,课程发布后学习者在网站可以搜索到课程,然后查看课程的详细信息,进一步选课、支付、在线学习。 下边是课程编辑与发布的整体流程&#…

Java中的 this 关键字是什么意思? this() 又是什么?

目录 问题问题一:什么是this关键字?问题二:什么是this()? 问题 问题一:什么是this关键字? 定义:this 代表当前对象。这个定义比较抽象,举例来回答。 思考一个问题:如果没有 this 会怎样&…

uniapp+vue3嵌入Markdown格式

使用的库是towxml 第一步:下载源文件,那么可以git clone,也可以直接下载压缩包 git clone https://github.com/sbfkcel/towxml.git 第二步:设置文件夹内的config.js,可以选择自己需要的格式 第三步:安装…

【国潮】软件本土化探索

文章目录 一、国产-操作系统银河麒麟(Kylin)操作系统华为鸿蒙系统(HarmonyOS)统信UOS深度Deepin 二、国产-服务器华为鲲鹏:飞腾:海光:兆芯:龙芯:申威: 三、国…

2024-07抖音/快手/小红书/视频号/美团无人直播技术:最新不封号无人直播的操作方法详细介绍

2024年最新研究出来的无人直播技术,目前不封号,用途大大的,可带货,可引流,可获客。 手机自动直播源码通常涉及到实时流媒体技术和应用开发,它涉及以下几个关键部分: 摄像头接入:使用…

neo4j 图数据库:Cypher 查询语言、医学知识图谱

neo4j 图数据库:Cypher 查询语言、医学知识图谱 Cypher 查询语言创建数据查询数据查询并返回所有节点查询并返回所有带有特定标签的节点查询特定属性的节点及其所有关系和关系的另一端节点查询从名为“小明”的节点到名为“小红”的节点的路径 更新数据更新一个节点…

基于jeecgboot-vue3的Flowable流程-集成仿钉钉流程(四)支持json和xml的显示

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 1、相应的界面前端代码 <template><div class"formDesign"><FlowDesign :process"process" :fields"fields" :readOnly"readOnly&quo…

微信小程序毕业设计-教育培训系统项目开发实战(附源码+论文)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计…

【机器学习】使用决策树分类器预测汽车安全性的研究与分析

文章目录 一、决策树算法简介决策树的结构分类和回归树 (CART)决策树算法术语决策树算法直觉 二、属性选择度量信息增益熵 基尼指数计算分割基尼指数的步骤 三、决策树算法中的过度拟合避免过度拟合的方法 四、导入库和数据可视化探索性数据分析重命名列名查看数据集的总结信息…

double和float的区别与使用

double和float类型的区别与使用 在Java中&#xff0c;double和float都是基本数据类型&#xff0c;用于表示浮点数&#xff08;即带有小数点的数&#xff09;。 它们在精度和范围上有所不同&#xff1a; double类型提供了更高的精度和更大的范围&#xff0c;而float类型则精度更…

类似评论、省市区这种具有层次结构的数据表怎么设计?

业务功能模块 评论、回复模块省市区表 设置一个给每个数据设置一个parent_id 例如&#xff1a; 某个视频下a写了条评论&#xff0c;那a的parent_id就是0;b回复了a&#xff0c;那b的parent_id就是a的id;c回复了b&#xff0c;那c的parent_id就是b的id; 这样&#xff0c;所有评论…

MATLAB备赛资源库(1)建模指令

一、介绍 MATLAB&#xff08;Matrix Laboratory&#xff09;是一种强大的数值计算环境和编程语言&#xff0c;特别设计用于科学计算、数据分析和工程应用。 二、使用 数学建模使用MATLAB通常涉及以下几个方面&#xff1a; 1. **数据处理与预处理**&#xff1a; - 导入和处理…

LeetCode加油站(贪心算法/暴力,分析其时间和空间复杂度)

题目描述 一.原本暴力算法 最初的想法是&#xff1a;先比较gas数组和cost数组的大小&#xff0c;找到可以作为起始点的站点(因为如果你起始点的油还不能到达下一个站点&#xff0c;就不能作为起始点)。当找到过后&#xff0c;再去依次顺序跑一圈&#xff0c;如果剩余的油为负数…

java使用poi-tl模版引擎导出word之if判断条件的使用

文章目录 模版中if语句条件的使用1.数据为False或空集合2.非False或非空集合 模版中if语句条件的使用 如果区块对的值是 null 、false 或者空的集合&#xff0c;位于区块中的所有文档元素将不会显示&#xff0c;这就等同于if语句的条件为 false。语法示例&#xff1a;{{?stat…

FUSE(用户空间文件系统)命令参数

GPT-4 (OpenAI) FUSE (Filesystem in Userspace)是一个允许创建用户空间文件系统的接口。它提供了一个API&#xff0c;让开发者在未修改内核代码的情况下&#xff0c;通过自己的程序实现文件系统。FUSE 文件系统通常通过 mount 命令来挂载&#xff0c;而且这个命令可以接受各…

【福利】代码公开!咸鱼之王自动答题脚本

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 微信或QQ打开咸鱼之王小程序&#xff0c;进入答题界面&#xff0c;运行main.py。期间不要动鼠标。 可自行更改代码来适配自己的需求~ 可以按照示例图片…

用QFramework重构飞机大战(Siki Andy的)(上)(00-05 到游戏界面之前的所有面板)

GitHub // 官网的 全民飞机大战&#xff08;第一季&#xff09;-----框架设计篇&#xff08;Unity 2017.3&#xff09; 全民飞机大战&#xff08;第二季&#xff09;-----游戏逻辑篇&#xff08;Unity 2017.3&#xff09; 全民飞机大战&#xff08;第三季&#xff09;-----完善…