首页 > 系统相关 >Volatile关键字以及JMM内存模型

Volatile关键字以及JMM内存模型

时间:2024-10-11 12:46:57浏览次数:10  
标签:版本号 线程 内存 Volatile JMM 操作 排序 进行

JMM内存模型:

这个简单来说就是一个规范,对数据进行计算的时候先从主内存中读取到PC寄存器然后进行计算之后将计算的结果最后再放入到主内存中

下面以 i++的计算过程为例子:

引申出这种情况下的三大特性(线程安全):

1.原子性: 当线程对资源进行操作的时候不能被其他线程所打断

例子: 简单来说当我有多个线程对i 进行+1操作的时候总共1万次那么最终i的结果也必须是一万次

2.可见性:  当一个线程对共享资源进行操作完成之后其他操作的线程会立刻得到这个线程操作之后的结果

例子: 当我一个线程将 i从0变为1的时候 ,那么其他线程对i操作的线程进行+1操作的时候必须是对i=1这个值进行一个操作

3.顺序性:程序的编写的顺序和执行的顺序是一致的不会出现指令重排序

指令重排序:在我看来就是一个优化的手段 分为:

编译器重排序:编译器会重新安排指令的顺序

处理器重排序:可以先执行某个指令也可以后执行某个指令

但是无论是哪种重排序都不能影响最终的正确的结果

 Volatile关键字(只能解决顺序性以及可见性但是不能解决原子性)

原因:
1.解决可见性是通过MESI缓存一致性协议:

简单来说就是通过总线的事件监听来进行一个保证

每一个PC寄存器里面都是有三个缓存(L1 L2 L3)

从L1到L3是体积是越来越大的那么成本就是越来越低 速度相对来说也就是越来越慢(毕竟一分价钱一分货),那么PC获得数据的时候会优先从三个缓存中读取数据如果没有的话那么就会从主内存中读取数据(提高效率的一个过程)

如图:

2.解决顺序性是通过添加读写屏障:对数据进行读写操作的前后添加读写屏障

读屏障:会确保所有的读取操作都已完成,并且任何后续的读取或写入操作不会被重排序到此屏障之前。

写屏障:会确保所有之前的写操作都已完成

3.不能解决原子性的原因: 是因为有一种特殊的情况的发生,有可能会出现多个PC寄存器同时从主内存中读取数据,然后同时进行+1的操作然后再将计算之后的数据同时刷入到主内存中。
解决原子性的方法:

1.可以通过锁机制来进行一个限制(这个方法是比较降低整体的系统的性能的)

2.可以通过CAS操作通过对比一个版本号(这个就是为了解决ABA问题)来保证操作的原子性

CAS操作:

这个自旋是可以进行控制的

ABA问题如图所示: 

由于竞争CPU资源的原因导致线程2最后才进行操作,但是线程2在正常的情况下是操作失败了,但是由于线程3的操作使得线程2操作成功了,这个就是一个问题了

解决:添加版本号,当线程进行操作的时候处理比较数值还要比较版本号,如果版本号不对的话那么操作也是失败的

标签:版本号,线程,内存,Volatile,JMM,操作,排序,进行
From: https://blog.csdn.net/2201_75397629/article/details/142847870

相关文章

  • JVM系列(四) -内存布局详解
    一、摘要熟悉Java语言特性的同学都知道,相比C、C++等编程语言,Java无需通过手动方式回收内存,内存中所有的对象都可以交给Java虚拟机来帮助自动回收;而像C、C++等编程语言,需要开发者通过代码手动释放内存资源,否则会导致内存溢出。尽管如此,如果编程不当,Java应用程序......
  • 【C/C++内存管理】
    【知识预告】C/C++内存分布C语言中动态内存管理方式C++内存管理new和delete的实现原理常见面试题内存泄漏1C/C++内存分布intglobalVar=1;staticintstaticGlobalVar=1;voidTest(){ staticintstaticVar=1; intlocalVar=1; intnum1[10]={1,2,3,......
  • 内存映射和共享内存
    内存映射(Memory-mappedfile)和共享内存(Sharedmemory)都是进程间通信(IPC)的机制,但它们在实现方式和使用场景上有一些区别:内存映射(Memory-mappedfile):内存映射是一种将文件或设备的内容映射到进程的地址空间的技术。这样,进程可以像访问普通内存一样访问文件内容。它通常用于文......
  • 谈JVM xmx, xms等内存相关参数合理性设置
    作者:京东零售刘乐上一篇文章说到JVM垃圾回收算法的两个优化标的:吞吐量和停顿时长,并提到这两个优化目标是有冲突的。那么有没有可能提高吞吐量而不影响停顿时长,甚至缩短停顿时长呢?答案是有可能的,提高内存占用(MemoryFootprint)就有可能同时优化这两个标的,这篇文章就来聊聊内存相关......
  • 5565反射内存卡是什么
    5565反射内存卡是一种高速、高效的数据传输设备。它主要用于设备间的高速数据传输,可通过多块接口板进行组网,组成实时光纤反射内存网络。5565系列反射内存卡具有众多特点。技术参数方面,光纤速率2.125G,传输过程无需CPU参与,支持环形和星型拓扑结构,33MHZ/66MHZ64-BIT/32-BI......
  • 虚拟内存能不能完全关了?太占空间了……
    前言这几天咱们提到关于Swap区(就是Linux上的数据交换分区),在Windows上这个功能被称为虚拟内存。前段时间(应该是很早之前),小白写过一篇关于虚拟内存的文章:Windows调大虚拟内存来代替升级物理运行内存(RAM)真的有用吗?可见,虚拟内存只能缓解物理运行内存一时的不足,如果要长期使用......
  • mysql占用内存过大问题排查
    如果MySQL占用内存过高,可以按照以下步骤进行排查:一、检查MySQL配置参数查看 innodb_buffer_pool_size:这个参数决定了InnoDB存储引擎缓冲池的大小,它会占用大量内存。如果设置得过大,可能导致内存占用过高。可以通过查询 SHOWVARIABLESLIKE'innodb_buffer_pool_size......
  • 43 C 程序动态内存分配:内存区域划分、void 指针、内存分配相关函数(malloc、calloc、re
    目录1 C程序内存区域划分1.1代码区(CodeSection)1.2全局/静态区(Global/StaticSection)1.3栈区(StackSection)1.4 堆区(HeapSection)1.5动态内存分配2void指针(无类型指针)2.1void指针介绍2.2void指针的作用2.3void指针的特点2.4 void指针类......
  • Rstudio占用内存过大
    在R中,尤其是在使用RStudio时,如果数据集很大,全部加载到内存可能会导致内存不足的问题。为了优化内存使用,可以考虑以下几种加载策略:1.按需加载数据使用data.table或dplyr包的功能,可以按需加载数据,而不是将整个数据集加载到内存中。例如,可以使用fread()函数从CSV文件......
  • 怎么手动在rstudio中释放内存?
    在RStudio中手动释放内存的几种方法如下:1.使用gc()函数R提供了gc()函数,可以用来强制R进行垃圾回收,从而释放未使用的内存。可以在R控制台中输入:gc()2.清除对象如果有不再需要的对象,可以使用rm()函数删除它们,并随后调用gc()函数。例如:#删除特定对象rm(obj......