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

前言

前一阵在看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://xiahunao.cn/news/3224490.html

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

相关文章

个人面试总结

写在前面:以下是自己在拟录用后回顾总结的了一下当时面试题目,把标答写了出来,供以后复习所使用,希望大家理性食用~~ 预祝大家都能找到心仪的工作 笔试题目: 1.1. java中Collection和Collections的区别 Collection…

vue3+antdv仿百度网盘样式文件夹管理组件

实现: 默认进入页面时,文件夹全选;文件夹状态,以及文件夹内的文件选择状态,与组件联动文件夹数量,根据后端数据动态生成 实现思路: 将后端数据存到vuex中,增加(多选框…

基于vue的可视化大屏

要提前准备一个xinyang.json文件 可以在这个网站下载 DataV.GeoAtlas地理小工具系列 (aliyun.com) 代码结构 总框架代码&#xff1a; <template><div><div class"center"><center-left /><center-map /><center-right /><…

PPI(每英寸像素数)、DPI(每英寸点数)和Pixel(像素)的区别和联系?

一、定义 PPI、DPI和Pixel是图像处理、打印和显示领域中常用的三个概念&#xff0c;它们之间既有区别又有联系。以下是对这三个概念进行分别讲解&#xff1a; 1. PPI&#xff08;Pixels Per Inch&#xff09;&#xff0d;即每英寸像素数&#xff0c;是图像分辨率的一种表示方…

技术速递|VS Code Java 6月更新 - 项目设置功能增强!大量 Spring 新特性

作者&#xff1a;Nick Zhu 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎阅读 Visual Studio Code for Java 的六月更新&#xff01;在这篇博客中&#xff0c;我们将分享项目设置项目的重要更新以及一系列 Spring 的功能改进&#xff0c;让我们开始吧&#xff01; 项目设…

AI论文作图——如何表示模型参数冻结状态

一、LOGO &#x1f525; win10win11 ❄️ win10win11 二、注意事项&#xff1a; 根据电脑系统&#xff0c;选择对应的版本。 参考&#xff1a; 【AI论文作图】如何表示模型参数冻结状态&#xff1f;

微信小程序 - 本地存储 增加有效期

小程序的本地存储API提供了wx.setStorageSync和wx.setStorage来存储数据&#xff0c;注意的是&#xff0c;小程序的本地存储并没有明确的有效期设置&#xff0c;存储的数据在不超过限制的情况下&#xff0c;会一直保留。 一、小程序本地存储API 小程序的本地存储API提供了设置…

容器docker

文章目录 前言一、docker1.1 为什么有docker1.2 docker架构1.3 docker 安装1.4 docker中央仓库1.5 docker 基本指令1.6 docker数据卷&#xff0c;挂载例&#xff1a;nginx 数据卷挂载例&#xff1a;mysql 本地持久化 1.7 镜像制作镜像结构dockerfile基础指令容器生成镜像 1.8 d…

C++笔试强训3

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、选择题1-5题6-10题 二、编程题题目一题目二 一、选择题 1-5题 如图所示&#xff0c;如图所示p-3指向的元素是6&#xff0c;printf里面的是%s&#xff0c;从6开…

带有子节点的树状表的父节点拖动排序#Vue3#Sortable插件

带有子节点的树状表的父节点拖动排序#Vue3#Sortable插件 使用Sortable插件这里要保证获取到的是父节点的下标&#xff0c;属性newDraggableIndex获取到的就是只有父节点的下标。设置子节点不能被拖动&#xff0c;最后在逐个调用接口进行数据库中顺序的更新。 <template>…

层次分析法上课笔记

欢迎来到一夜看尽长安花 博客&#xff0c;您的点赞和收藏是我持续发文的动力 对于文章中出现的任何错误请大家批评指出&#xff0c;一定及时修改。有任何想要讨论的问题可联系我&#xff1a;3329759426qq.com 。发布文章的风格因专栏而异&#xff0c;均自成体系&#xff0c;不足…

Profibus转ModbusTCP网关模块实现Profibus_DP向ModbusTCP转换

Profibus和ModbusTCP是工业控制自动化常用的二种通信协议。Profibus是一种串口通信协议&#xff0c;它提供了迅速靠谱的数据传输和各种拓扑结构&#xff0c;如总线和星型构造。Profibus可以和感应器、执行器、PLC等各类设备进行通信。 ModbusTCP是一种基于TCP/IP协议的通信协议…

使用八股搭建神经网络

神经网络搭建八股 使用tf.keras 六步法搭建模型 1.import 2.train, test 指定输入特征/标签 3.model tf.keras.model.Sequential 在Squential,搭建神经网络 4.model.compile 配置训练方法&#xff0c;选择哪种优化器、损失函数、评测指标 5.model.fit 执行训练过程&a…

python开发prometheus exporter--用于hadoop-yarn监控

首先写python的exporter需要知道Prometheus提供4种类型Metrics 分别是&#xff1a;Counter, Gauge, Summary和Histogram * Counter可以增长&#xff0c;并且在程序重启的时候会被重设为0&#xff0c;常被用于任务个数&#xff0c;总处理时间&#xff0c;错误个数等只增不减的指…

昇思25天学习打卡营第16天|Vision Transformer图像分类

昇思25天学习打卡营第16天|Vision Transformer图像分类 前言Vision Transformer图像分类Vision Transformer&#xff08;ViT&#xff09;简介模型结构模型特点 环境准备与数据读取模型解析Transformer基本原理Attention模块 Transformer EncoderViT模型的输入整体构建ViT 模型训…

xcode项目添加README.md文件并进行编辑

想要给xcode项目添加README.md文件其实还是比较简单的&#xff0c;但是对于不熟悉xcode这个工具的人来讲&#xff0c;还是有些陌生&#xff0c;下面简单给大家讲一下流程。 选择“文件”>“新建”>“文件”&#xff0c;在其他&#xff08;滚动到工作表底部&#xff09;下…

k8s record 20240708

一、PaaS 云平台 web界面 资源利用查看 Rancher 5台 CPU 4核 Mem 4g 100g的机器 映射的目录是指docker重启后&#xff0c;数据还在 Rancher可以创建集群也可以托管已有集群 先docker 部署 Rancher&#xff0c;然后通过 Rancher 部署 k8s 想使用 kubectl 还要yum install 安…

leetcode--验证二叉搜索树

leetcode地址&#xff1a;验证二叉搜索树 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左 子树 只包含 小于 当前节点的数。 节点的右子树只包含 大于 当前节点的数。 所有左子树和右子树自身必…

71.WEB渗透测试-信息收集- WAF、框架组件识别(11)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;70.WEB渗透测试-信息收集- WAF、框架组件识别&#xff08;10&#xff09;-CSDN博客 如果有…

人工智能和机器学习 (复旦大学计算机科学与技术实践工作站)20240703(上午场)人工智能初步、mind+人脸识别

前言 在这个科技日新月异的时代&#xff0c;人工智能&#xff08;AI&#xff09;已经逐渐渗透到我们生活的方方面面&#xff0c;从智能家居到自动驾驶&#xff0c;无一不彰显着AI的强大潜力。而人脸识别技术作为AI领域的一项重要应用&#xff0c;更是以其高效、便捷的特点受到了…