技术解析

Java 内存模型中的工作内存跟主内存的物理概念是什么
0
2021-06-02 13:07:49
idczone
本地内存=cpu国外服务器 高速缓存?
主内存=内存?
不知道这样理解对不对,看到网上有人说本地内存=cpu 寄存器里的内容,但是我细细一想,如果指的是 cpu 寄存器,那假设有个 cpu 是单核的,只有一个核心,也就是说只有一个寄存器,那本地内存跟主内存之间的可见性问题不就不存在了?因为内存就一份,本地内存也就一份了(一个寄存器)。
求解答。
cpu 的每个核都有自己的工作内存.. 什么 l1,l2,l3, 寄存器.. 目的就是优化访问主内存的耗时.
单个核的话我理解也是可以降低访问主存的耗时的.
楼主可以去看看访问主存, l1, l2, l3, 寄存器各需要多少时间..

CPU 里面的叫 Cache 和 Register,内存上的叫 Memory 。
CPU 在计算时没法直接访问 Memory,会先从 Memory 搬到 Cache 里面然后再从 Cache 里读。
概念这种不太清楚的话可以看看英文的。

Java 内存模型是对硬件内存、缓存的一层抽象 主要屏蔽 OS 和平台的差异化 可以让你在写 Java 代码的时候不需要过度关注访问内存时的细节

了解下存储器的分层体系结构吧,再了解下地址空间,虚拟存储器的概念。

找本操作系统的书看看
感觉是现代计算机基本的架构没搞明白

读一下深入理解计算机原理,基础要打牢啊

所以 java 内存模型里的工作内存就是 CPU 里的 Cache,是这个意思吗?

谢谢楼上所有的回复。。我确实对操作系统的一些概念很模糊

不是,完全不是一样的概念。
我说的那个是硬件本身的东西,物理上存在的。
Java 的 JVM 本身是个抽象的概念,它只是个虚拟机,不是物理上的机器,是运行在操作系统上的。
总的来说就是 CPU+Memory -> OS -> JVM 这样的关系。
在两层抽象以后,Java 内存模型里面的这些东西并没有能完全对应的物理概念。它只是在 JVM 这个抽象层次上对物理概念的一个模拟而已。

很感谢老哥的细心解答。我之前是觉得 java 内存模型跟 CPU 是可以联系起来的:JVM 是操作系统里的一个用户态,一个进程,要操作硬件只能通过操作系统内核的一些指令去执行,内核的这些指令就可以直接或间接地给 CPU 发送硬件级别的指令了。这样 JVM 就跟 CPU 联系起来了,所以我就很想知道 java 内存模型里的概念,是不是在 CPU 是能找到对应的物理实现的。

Java 内存模型是建立在抽象虚拟机上的,所有的描述都是针对这个实际并不存在的机器模型。但是具体 JVM 实现,还是要落地的,在不同的 arch 下映射到不同的硬件。
这个有点类似 OSI 7 层参考模型,对应到实际网络模型时只有 4 层了。

主内存和工作内存这概念就是误人子弟,我找了半天发现只有一个出处,就是周志明的那本 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

/> jmm 规范
https://download.oracle.com/otn-pub/jcp/memory_model-1.0-pfd-spec-oth-JSpec/memory_model-1_0-pfd-spec.pdf?AuthParam=1620902039_0254b321773beb67d4ea76e5fff7b71e

推荐阅读一下《计算机体系结构:量化研究方法》第五章,虽然翻译比较古老,但是应该也能理解

不太熟 Java,但是我理解 Java 的虚拟机和普通 CPU 形式还不太一样
JVM 和 .Net 的 CLR 是 stack machine,运行的时候指令靠一个 stack 来回弹就够了
普通 CPU 的指令集操作的是 register machine,有 N 个寄存器地址
Lua 的虚拟机倒是 register machine

你就记得,一个是 CPU 能直接看到,一个是 CPU 查找后能看到

main memory 和 working memory 这两个印象是在 JDK 1.5/1.6 旧文档中有提及,现在文档没再提这个,而周志明的书就是按照当时 JVM 文档翻译过来的,虽然书说明为逻辑概念,但 main memory 就是直观理解的内存,而 working memory 就是指 cpu cache 一类。

我就是看了周志明老师的那本书才有此疑惑。像楼上那位老哥说的,这之间隔着两层抽象,应该是无法对应上的。

感谢推书。一定会看,也谢谢老哥的详细解答

《 Java 并发编程实战》书中也有对 work memory 跟 main memory 的介绍

其实我还有个疑惑。。。JVM 中的程序计数器( PC 寄存器)的物理实现是不是就类似于 CPU 中寄存器?
因为这两者都是用于线程切换时保存当前线程执行的指令位置,主要是为了当前线程重新获得时间片之后的后续执行。如果说得不对大家就当看个笑话哈哈。。

难怪从来没见过这个概念。。。看到这标题直接懵了我


对应 eip

搜索一下就找到原文说法了,docs.oracle.com/javase/specs/jvms/se6/html/Threads.doc.html,就是 cpu cache 无疑

Every thread has a working memory in which it keeps its own working copy of variables that it must use or assign. As the thread executes a program, it operates on these working copies. The main memory contains the master copy of every variable. There are rules about when a thread is permitted or required to transfer the contents of its working copy of a variable into the master copy or vice versa.

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服