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

22 篇文章 1 订阅

在学习Java多线程编程里, volatile 关键字保证内存可见性的要点时,看到网上有些资料是这么说的:线程修改一个变量,会把这个变量先从主内存读取到工作内存;然后修改工作内存中的值,最后再写回到主内存

内存可见性问题的表述为:t1 频繁读取主内存,效率比较低,就被优化成直接读自己的工作内存;t2 修改了主内存的结果,但由于 t1 没有读主内存,导致修改不能被识别到,最终导致代码出现bug。

上面这段话中提到的“工作内存”、“主内存”这两个概念,这里作一下简单的介绍。

与我们平时的使用习惯有些不同:“工作内存”指的并不是真正的内存(内存条),而是CPU寄存器与缓存;而“主内存”,才是我们所说的内存条。

这两个词语翻译自英文 work memory(工作内存) 和 main memory(主内存)。但事实上,memory 这个英文单词并不一定就特指内存条,它也可以翻译成“存储区”,单纯地表示“一个用来存储的空间”。不过虽然如此,在进行中文翻译的时候,一般还是将 memory 翻译为“内存”更多一些。因此,work memory 就仍然被翻译为了“工作内存”。

这样一来就容易让我们误会:难道内存条还分为不同的种类,有工作用的内存和主的内存之分吗?其实不然,实际上我们所说的“工作内存”,应该理解为“工作存储区”更合适,它只是CPU寄存器和缓存,而与内存条无关。

上面的这一套的说法,也称为JMM(Java Memory Model),即Java内存模型。JMM的概念来自于 jvm 规范文档,相当于是官方给出的这套说法。

为什么 Java 官方使用的是主内存、工作内存这样自己发明的新术语,而不直接使用 CPU 寄存器,缓存,内存这样更为通用术语呢?主要考虑到的一点是:Java是跨平台的。

Java 是跨平台的,这意味着它必须:

1、兼容多种操作系统。

2、兼容多种硬件设备,尤其是 CPU。

而不同的硬件之间,CPU会有比较大的差异。例如,以前的CPU上只有寄存器,而现在的CPU上除了寄存器,还有缓存;并且有的CPU还有好几个缓存(常见的是三级缓存:L1、L2、L3)。

博主电脑的三级缓存及空间

这样,Java官方文档中要指代相关的概念,如果只提“CPU寄存器”,那就太不严谨了,因为还有各种缓存;如果使用“CPU寄存器和缓存”这一指代,则又过于麻烦。因此,官方干脆发明了一个新的术语:work memory 来代表CPU寄存器和缓存(CPU内部的存储空间)。


下面再简单介绍一下CPU缓存(Cache)。

CPU 读寄存器的速度很快,要比读内存快 3 到 4 个数量级。

缓存的读取速度介于寄存器和内存之间:三级缓存中,L1 最快(仍然比寄存器慢),但空间最小;L3 最慢(仍然比内存快很多),但空间最大。

(任务管理器 -> 性能 中可以查看本机的三级缓存的空间信息。)

实际中, CPU 尝试读一个内存数据,会经历以下步骤:

1、先看看寄存器里有没有;

2、没有,再看下 L1 有没有;

3、没有,再看下 L2有没有;

4、没有,再看下 L3 有没有;

5、没有,再看下内存有没有……

CPU这样做的目标是为了效率更高。CPU访问缓存的速度要比访问内存更快,即使有了上述几个步骤,也要比直接在内存中找数据更快。

缓存的大小对于程序效率的具体影响,也看实际的应用场景。例如,AMD 7950x3D 相比于之前的型号,没有什么大的更改,主要就是提升了 L3 的缓存空间(提升到了256MB)。这样一来,在游戏场景下电脑性能的提升就很大了。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值