主内存和工作内存这概念就是误人子弟,我找了半天发现只有一个出处,就是周志明的那本 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.pdfIntel 乱序执行的规范
http://www.cs.cmu.edu/~410-f10/doc/Intel_Reordering_318147.pdfJava 同步规范
https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html