JMM(Java Memory Model java内存模型

目标:

搞清楚高并发场景下,java内存模型是怎么支持的,对象在内存中是怎么布局的?

 

目录

目标:

搞清楚高并发场景下,java内存模型是怎么支持的,对象在内存中是怎么布局的?

1.硬件层的并发优化基础知识

 2.多核CPU线程访问条件下数据不一致性问题?

 原因:

 解决方案:

缓存行

MESI带来的伪共享问题

3.CPU的乱序执行问题

 CPU乱序执行的原因

CPU乱序执行的表现

读指令的乱序执行

写指令的合并执行(write combining)

如何保证特定情况下,不乱序

CPU级别采用内存屏障保证或者Java的汇编指令 Lock :

JVM级别再进行规范

Java代码级别采用volatitle关键字保障

1.字节码层面(.class文件)

2.JVM层面

3. os和硬件层面


1.硬件层的并发优化基础知识

备注:

L3高速缓存也是在主板上,所以也是被所有的CPU共享的。

L0寄存器,存储着CPU内部核心的几个计算单元,用于计算。

离CPU越近容量越小,成本越高,速度越快。

比如说 有个变量int a=3;在 L2上,计算时CPU会先把a  load到L1上,然后被L0直接加载计算。

 2.多核CPU线程访问条件下数据不一致性问题?

 原因:

两个CPU彼此独立,但是都是操作CPU的共享区域的数据,比如一个CPU 对X作了修改,另一CPU是不能及时知道的。这就造成了共享区域的数据对各个不同的CPU 来说数据不一致问题。

 解决方案:

老的CPU:

总线锁会锁住总线,使得其他CPU甚至不能访问内存中其他的地址,因而效率较低

 新的CPU

现在CPU的数据一致性,通过缓存锁+总线锁来解决

https://www.cnblogs.com/z00377750/p/9180644.html

新的CPU采用缓存锁(缓存一致性)来解决,一致性的协议又很多,Intel采用了MESI协议。

 CPU会对缓存的内容做状态标记,如果读取的内容相对于主存来说被更改过(自己修改过),则状态改这个内容对应的缓存行状态改为Modified(别的cpu对这个内容所在缓存行状态就是Invalid);如果读取的内容自己独享,就将其所在缓存行状态改为Exclusive。如果读取的内容,我读的时候别人也在读取,该内容所在缓存行状态就修改为Shared。如果读取的内容别的cPU已经修改过,说明我的读的内容无效了,该内容所在缓存行  状态就变为Invalid。

缓存行

现在cpu 缓存数据,不是一个字节一个字节来缓存,而是以一个缓存行,默认64字节。一次性加载到缓存中。

MESI带来的伪共享问题

如果自己要修改某个数据A,发现它的状态已经变为了Invalid,则去缓存中再加载一次。

思考这个场景: x,y位于同一个缓存行,cpu1只想的读取x,cpu2只想读取y
由于读取时必须以缓存行为单位,cpu1 读取x时,也读取到了y。 cpu1改变了x的值后,x所在的缓存行的状态在CPU1中就会被改变为modified, 在cpu2中x所在的缓存行状态就会变为invalid。 因此,cpu2 本来想读取y,一看y 所在缓存行状态变为了 invalid 。就会去重新加载y所在的缓存行。问题是cpu2其实只关注y,y的值也没有变化,而x的变化和它无关。因此本质上cpu2不需要去进行这次缓存加载的。
同理cpu2对y作了修改,后cpu1也得重新加载x所对应的缓存行。
这样的重新加载是一种时间和资源的浪费,缓存一致性或者说缓存锁解决数据安全问题的的同时带来的 这个多次非必要加载缓存问题被称为伪共享问题。

3.CPU的乱序执行问题

首先明确一个事实,CPU执行指令的时候是乱序执行的。

 CPU乱序执行的原因

https://www.cnblogs.com/liushaodong/p/4777308.html

CPU的执行指令在内存中做一些操作,因为CPU的执行速度相较于内存至少时100倍,所以CPU不能干等着执行结果,为了提高效率,CPU就 在一条指令执行结束之前,继续执行别的指令。这种不按照程序的编写顺序执行的情况,被称为CPU的乱序执行问题。乱序变现在读指令的乱序,和写指令的乱序。

当然乱序执行不能带来程序的最终执行结果的乱序。所以,计算机底层,对CPU的乱序执行也是作了规范,也保障乱序执行的结果是正确的。提高了执行效率,也保证执行结果的正确性。

CPU乱序执行的表现

读指令的乱序执行

CPU在执行一条读指令后等待该指令执行完(或者返回结果)前,回去执行另一条与该指令没有依赖关系的读指令

写指令的合并执行(write combining)

合并写:

CPU将计算好的值A缓存到L1,如果缓存失败,就会缓存到L2,再此过程中L2相对于CPU太慢了,如果这个过程中A值被改写了几次。CPU会直接将改写的最终结果刷到L2。这种情况被称为合并写

如何保证特定情况下,不乱序

某些特定场景写要保证顺序,如何保障有序性

CPU级别采用内存屏障保证或者Java的汇编指令 Lock :

sfence:在sfence指令前的写操作当必须在sfence指令后的写操作前完成。
lfence:在lfence指令前的读操作当必须在lfence指令后的读操作前完成。
mfence:在mfence指令前的读写操作当必须在mfence指令后的读写操
作前完成。
原子指令,如x86上的”lock …” 指令是一个FullBarrier,执行时会锁住内存子系统来确保执行顺
序,甚至跨多个CPU。Software Locks通常使用了内存屏障或原子指令来实现变量可见性和保持
程序顺序

JVM级别再进行规范

LoadLoad屏障: 对于这样的语句Load1; LoadLoad; Load2,
在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。

StoreStore屏障:
对于这样的语句Store1; StoreStore; Store2,
在Store2及后续写入操作执行前,保证Store1的写入操作对其它处理器可见。

LoadStore屏障:
对于这样的语句Load1; LoadStore; Store2,
在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕。

StoreLoad屏障: 对于这样的语句Store1; StoreLoad; Load2,
​ 在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。

 备注:这些规范的实现,是依赖于硬件级别的原理来实现的。具体用哪些硬件原理,怎么组合操作,JVM自己决定。

Java代码级别采用volatitle关键字保障

1.字节码层面(.class文件)

被volatile 修饰的变量在.class二进制字节码文件中多了一个acc_volatile 标记

2.JVM层面

JVM对被acc_volatile  修饰的变量,也即 .class文件中被 acc_volatile修饰的变量:

        如果它是写操作指令,则在该写操作前面加一个 StoreStoreBarrier ,后面加一个StoreLoadBarrier ,保证该指令与上下两个指令不重排序

        如果它是读操作指令,则在该读操作前面加一个 LoadLoadBarrier ,后面加一个LoadStoreBarrier ,保证该指令与上下两个指令不重排序

3. os和硬件层面

windows 上采用Lock 指令和MESI 实现,Linux我忘了,哈哈哈

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

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

相关文章

若依 ruoyi-vue el-select 多选框 全选 反选 全不选 查询功能

参考文章vueel-select下拉实现&#xff1a;全选、反选、清空功能 如图&#xff0c;优化代码&#xff0c;支持若依字典 import multipleSelect from /components/MultipleSelect/index.vuecomponents: { multipleSelect },<el-row><el-form-item label"分管领域…

ERA5再分析资料下载和处理成红黑图教程

ERA5再分析资料下载和处理教程 1.下载官网&#xff1a; https://cds.climate.copernicus.eu/cdsapp#!/dataset/reanalysis-era5-pressure-levels?tabform 下载之前需要注册网站的账号认证 选择需要的要素时间气压等要素&#xff0c;注意最后下载的数据格式是grib还是nc格式 …

Unity之PUN实现多人联机射击游戏的优化(Section 3)

目录 &#x1f4a3;一、准备工作 &#x1f4a3;二、生成弹头脚本的编写 &#x1f4a3;三、实现发射和伤害同步 手雷都加了在给狗剩加个火箭筒不过分吧。效果看GIF动图&#xff0c;分别是单机和联机的效果。 添加火箭筒依旧是在原有的基础上更改&#xff0c;我查看火箭筒模型…

8.基础乐理-纯八度

一个音听上去是高还是低&#xff0c;是由音的振动频率决定的&#xff0c;也就是每一秒多少 Hz 所决定的&#xff0c;Hz数越小音听上去就越低&#xff0c;Hz数越大音听上去就越大&#xff0c;钢琴从左到右&#xff0c;Hz数 在逐渐增大&#xff0c;当两个音的振动频率数越接近简单…

ARM汇编指令、指令中s后缀的作用、N、Z、C、V位有什么作用、ARM汇编启动代码

ARM汇编指令 学习arm汇编的主要目的是为了编写arm启动代码,启动代码启动以后,引导程序到c语言环境下允许。换句话说启动代码的目的是为了在处理器复位以后搭建c语言最基本的需求。因此启动代码的主要任务有: 初始化异常向量表; 初始化各工作模式的栈指针寄存器; 开启arm…

【深入解析spring cloud gateway】13 Reactive Feign的使用

问题引入 在gateway中如果使用feignClient的话&#xff0c;会报如下错误 java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-3at reactor.core.publisher.BlockingSingleSubscriber.bloc…

密码知识汇总

文章目录 密码学知识&#xff23;&#xff29;&#xff21;三要素机密性&#xff08;Confidentiality&#xff09;完整性&#xff08;Integrity&#xff09;可用性&#xff08;Availability&#xff09; 非安全信道的风险以及应对措施风险应对措施使用加密技术&#xff08;防窃…

在uni-app使用iconfont中的图标

uni-app 如何使用iconfont中的图标 在uni-app中使用Iconfont图标通常涉及以下几个步骤&#xff1a; 步骤一&#xff1a;获取Iconfont资源 访问 iconfont-阿里巴巴矢量图标库&#xff0c;注册并登录账号。 浏览或搜索所需的图标&#xff0c;将它们添加至购物车或直接创建项目进…

Ubuntu 23.10.1 nginx源码安装

注&#xff1a;以下所有命令均在root管理员模式下&#xff0c;若不是&#xff0c;请在所有命令前加sudo 1、安装依赖库 1.1、安装gcc g的依赖库 apt-get install build-essential apt-get install libtool1.2、安装pcre依赖库 apt-get update apt-get install libpcre3 lib…

【opencv】示例-ffilldemo 使用floodFill()函数进行区域泛洪填充

image mask mask #include "opencv2/imgproc.hpp" // 包含OpenCV图像处理头文件 #include "opencv2/imgcodecs.hpp" // 包含OpenCV图像编码头文件 #include "opencv2/videoio.hpp" // 包含OpenCV视频IO头文件 #include "opencv2/highgui.hp…

【分享】3种方法取消Word文档的“打开密码”

我们知道&#xff0c;Word文档可以设置“打开密码”&#xff0c;防止文档被随意打开&#xff0c;那后续不需要密码保护了&#xff0c;要怎么取消呢&#xff1f;不小心把密码忘记了还可以取消吗&#xff1f;不清楚的小伙伴一起来看看吧&#xff01; 如果是Word文档不再需要密码…

Open3D(C++) 0~1归一化到0~255

目录 一、算法原理二、代码实现三、结果展示四、参考链接本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 0-1归一化到0~255的计算原理如下: g ′ = 255 ∗

冯喜运:4.15汇市观潮:现货黄金美原油技术分析

【 黄金消息面分析】&#xff1a;周一(4月15日)亚市盘初&#xff0c;金价开盘跳涨13美元&#xff0c;报2357.71美元/盎司&#xff0c;随后延续涨势&#xff0c;最高触及2372.45美元/盎司&#xff0c;目前金价回落至2354.19美元/盎司&#xff0c;如果中东局势未进一步恶化&#…

通过注解实现接口入参检查

valid 通过注解实现接口入参检查 前言一、引入依赖二、使用步骤1.创建入参对象 request2.提供一个接口 controller3.全局异常捕获 GlobalExceptionHandler4.执行结果 总结 前言 作为一个后端开发&#xff0c;一般是不单独对接口参数的每个入参进行长度、最大值、最小值判断。 …

RN向上向下滑动组件封装(带有渐变色)

这段组件代码逻辑是出事有一个View和下面的块,下面的块也就是红色区域可以按住向上向下滑动,当滑动到屏幕最上面则停止滑动,再向上滑动的过程中,上方的View的背景色也会有个渐变效果,大概逻辑就是这样 代码如下 import React, {useEffect, useRef, useState} from react; impo…

爱自然生命力专项基金:“爱·启航”残障家庭教育援助项目帮扶上万残障家庭

为进一步积极践行社会责任&#xff0c;助力公益慈善事业&#xff0c;2017年2月爱自然生命力体系与中国下一代教育基金会开展相关合作&#xff0c;共同启动了中国下一代教育基金会爱自然生命力专项基金&#xff0c;并启动了基金第一个项目“爱启航残障家庭教育援助项目”&#x…

华为昇腾AI芯片加持,9.1k Star 的 Open-Sora-Plan,国产Sora要来了吗

Aitrainee | 公众号&#xff1a;AI进修生 哇&#xff0c;今天Github趋势榜第一啊&#xff0c;为了重现Sora&#xff0c;北大这个Open-Sora-Plan&#xff0c;希望通过开源社区力量的复现Sora&#xff0c;目前已支持国产AI芯片(华为昇腾&#xff09;&#xff0c;这回不用被卡脖子…

(学习日记)2024.04.17:UCOSIII第四十五节:中断管理

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

An Investigation of Geographic Mapping Techniques for Internet Hosts(2001年)第二部分

​下载地址:An investigation of geographic mapping techniques for internet hosts | Proceedings of the 2001 conference on Applications, technologies, architectures, and protocols for computer communications 被引次数:766 Padmanabhan V N, Subramanian L. An i…

【原创】springboot+mysql宠物管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…