Java 内存模型中的工作内存跟主内存的物理概念是什么

2021-05-13 15:07:10 +08:00
 fatyoung
本地内存=cpu 高速缓存?
主内存=内存?
不知道这样理解对不对,看到网上有人说本地内存=cpu 寄存器里的内容,但是我细细一想,如果指的是 cpu 寄存器,那假设有个 cpu 是单核的,只有一个核心,也就是说只有一个寄存器,那本地内存跟主内存之间的可见性问题不就不存在了?因为内存就一份,本地内存也就一份了(一个寄存器)。
求解答。
2655 次点击
所在节点    程序员
25 条回复
BBCCBB
2021-05-13 15:15:51 +08:00
cpu 的每个核都有自己的工作内存.. 什么 l1,l2,l3, 寄存器.. 目的就是优化访问主内存的耗时.

单个核的话我理解也是可以降低访问主存的耗时的.

楼主可以去看看访问主存, l1, l2, l3, 寄存器各需要多少时间..
Mithril
2021-05-13 15:24:19 +08:00
CPU 里面的叫 Cache 和 Register,内存上的叫 Memory 。
CPU 在计算时没法直接访问 Memory,会先从 Memory 搬到 Cache 里面然后再从 Cache 里读。
概念这种不太清楚的话可以看看英文的。
cqsc
2021-05-13 15:41:25 +08:00
Java 内存模型是对硬件内存、缓存的一层抽象 主要屏蔽 OS 和平台的差异化 可以让你在写 Java 代码的时候不需要过度关注访问内存时的细节
raaaaaar
2021-05-13 16:05:55 +08:00
了解下存储器的分层体系结构吧,再了解下地址空间,虚拟存储器的概念。
Jooooooooo
2021-05-13 16:10:20 +08:00
找本操作系统的书看看

感觉是现代计算机基本的架构没搞明白
seers
2021-05-13 16:13:38 +08:00
读一下深入理解计算机原理,基础要打牢啊
fatyoung
2021-05-13 16:35:17 +08:00
@Mithril 所以 java 内存模型里的工作内存就是 CPU 里的 Cache,是这个意思吗?
fatyoung
2021-05-13 16:36:34 +08:00
谢谢楼上所有的回复。。我确实对操作系统的一些概念很模糊
Mithril
2021-05-13 17:41:28 +08:00
@fatyoung 不是,完全不是一样的概念。
我说的那个是硬件本身的东西,物理上存在的。
Java 的 JVM 本身是个抽象的概念,它只是个虚拟机,不是物理上的机器,是运行在操作系统上的。
总的来说就是 CPU+Memory -> OS -> JVM 这样的关系。
在两层抽象以后,Java 内存模型里面的这些东西并没有能完全对应的物理概念。它只是在 JVM 这个抽象层次上对物理概念的一个模拟而已。
fatyoung
2021-05-13 18:03:21 +08:00
@Mithril 很感谢老哥的细心解答。我之前是觉得 java 内存模型跟 CPU 是可以联系起来的:JVM 是操作系统里的一个用户态,一个进程,要操作硬件只能通过操作系统内核的一些指令去执行,内核的这些指令就可以直接或间接地给 CPU 发送硬件级别的指令了。这样 JVM 就跟 CPU 联系起来了,所以我就很想知道 java 内存模型里的概念,是不是在 CPU 是能找到对应的物理实现的。
sagaxu
2021-05-13 19:34:07 +08:00
Java 内存模型是建立在抽象虚拟机上的,所有的描述都是针对这个实际并不存在的机器模型。但是具体 JVM 实现,还是要落地的,在不同的 arch 下映射到不同的硬件。

这个有点类似 OSI 7 层参考模型,对应到实际网络模型时只有 4 层了。
ljzxloaf
2021-05-13 19:53:48 +08:00
主内存和工作内存这概念就是误人子弟,我找了半天发现只有一个出处,就是周志明的那本 jvm 书。搜索“jmm work memory”或者“jmm main memory”都没搜到有用的结果。有时候这些过时的概念真的让人费解,比如分布式领域的“CAP”理论就是典型的例子。

了解 CPU 的人都知道,CPU 有个 l1 缓存,l1 缓存是每个核的本地缓存,那么就会出现一个对共享变量访问顺序的问题(或者叫一致性问题)。打个比方,CPU0 先修改了共享变量 X,CPU1 应该什么时候感知到这个修改,如果需要立即感知的话,CPU0 在修改的时候就需要把 CPU1 的本地 X 缓存( l1 )先清理掉,但是这样势必会导致 CPU 整体执行效率的下降,而如果不需要保证这点,那 CPU 效率就会提升很多。有人会觉得这种顺序肯定是要保证的吧,其实不一定的,比如在分布式存储上很多都是保证不了这一点,不还是有很多应用吗?单机和分布式是类似的,而多 CPU 已经是分布式架构了。
如果真的要强行类比的话,主内存好比是 PC 存储结构中的内存( L2 、L3 缓存也算),工作内存就好比是 L1 缓存(一些寄存器也算)。

为啥说是强行类比呢?因为有更好的类比方式。JVM 规范之于 java 应用来说就如同 ISA 之于 os 上的应用,不同的 ISA 对于多核环境下对共享内存的访问一致性有不同的规则,有的是完全不管顺序,有的可能会保证全局顺序,更多的是介于二者之间的(详情请看论文 1 section 7 );而 JVM 是跨平台的,不可能跟着 ISA 的规则走,那样的话同样的代码运行在不同的平台结果就会不一样,所以得制定一个统一的规则。目前描述这种偏序关系广泛采用的方式是 happens-before,java 也是采用的这种(好像一开始规定了一些乱七八糟的规范,但是我没找到周志明书上写的那些内容出处,如果有找到出处的同学麻烦 @我一下)。



CPU 缓存的概念性理解
http://www.puppetmastertrading.com/images/hwViewForSwHackers.pdf
Intel 乱序执行的规范
http://www.cs.cmu.edu/~410-f10/doc/Intel_Reordering_318147.pdf
Java 同步规范
https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html
ljzxloaf
2021-05-13 19:54:35 +08:00
ljzxloaf
2021-05-13 19:59:09 +08:00
@ljzxloaf #12 推荐阅读一下《计算机体系结构:量化研究方法》第五章,虽然翻译比较古老,但是应该也能理解
namelosw
2021-05-13 22:27:39 +08:00
不太熟 Java,但是我理解 Java 的虚拟机和普通 CPU 形式还不太一样

JVM 和 .Net 的 CLR 是 stack machine,运行的时候指令靠一个 stack 来回弹就够了

普通 CPU 的指令集操作的是 register machine,有 N 个寄存器地址

Lua 的虚拟机倒是 register machine
Michaelssss
2021-05-13 22:29:57 +08:00
你就记得,一个是 CPU 能直接看到,一个是 CPU 查找后能看到
halo117
2021-05-14 01:35:50 +08:00
@ljzxloaf main memory 和 working memory 这两个印象是在 JDK 1.5/1.6 旧文档中有提及,现在文档没再提这个,而周志明的书就是按照当时 JVM 文档翻译过来的,虽然书说明为逻辑概念,但 main memory 就是直观理解的内存,而 working memory 就是指 cpu cache 一类。
fatyoung
2021-05-14 09:58:14 +08:00
@halo117 我就是看了周志明老师的那本书才有此疑惑。像楼上那位老哥说的,这之间隔着两层抽象,应该是无法对应上的。
fatyoung
2021-05-14 09:58:56 +08:00
@ljzxloaf 感谢推书。一定会看,也谢谢老哥的详细解答
fatyoung
2021-05-14 10:12:24 +08:00
@ljzxloaf 《 Java 并发编程实战》书中也有对 work memory 跟 main memory 的介绍

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/776726

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX