【发布时间】:2018-06-06 12:29:02
【问题描述】:
我正在尝试了解 Java 内存模型,但一直未能得到关于 CPU 缓存的观点。
据我所知,在 JVM 中,我们有以下位置来存储本地和共享变量:
local variables -- on thread stack
shared variables -- in memory, but every CPU cache has a copy of it
所以我的问题是:为什么将局部变量存储在堆栈中,并将(缓存)共享变量存储在 CPU 缓存中?为什么不反过来(假设 CPU 缓存太昂贵而无法存储两者),我们将局部变量缓存在 CPU 缓存中,然后从内存中获取共享变量?这是 Java 语言设计的一部分还是计算机体系结构的一部分?
进一步:就像“CPU 缓存”听起来那么简单,如果多个 CPU 共享一个缓存会怎样?而在具有多级缓存的系统中,共享变量的副本将存储在哪一级缓存中?此外,如果多个线程在同一个 CPU 内核中运行,是否意味着它们共享同一组缓存的共享变量,因此即使未定义共享变量volatile,对变量的访问也是运行在同一 CPU 上的其他线程仍然可以立即看到吗?
【问题讨论】:
-
对于非原始类型,“变量的值” 只是 Java 中的 references-to 对象。 对象 本身不在堆栈中。字段总是与 对象 相关联,并且由于 对象 不在堆栈中。Java 内存模型对与字段读取/写入的发生关系相当宽松,即线程可见性问题经常发挥作用的地方。
-
对于 SO 问题而言,该主题过于广泛且不具体,但您也有几个不正确的假设。 “局部变量——在线程堆栈上”:这是概念性的 Java 架构,它可能与代码在 CPU 上的实际运行方式几乎没有关系。但它很可能大部分时间都存储在主内存中,并受制于 CPU 缓存中的缓存。并且不与其他线程共享。 “共享变量——在内存中,但每个 CPU 缓存都有它的副本”——不,CPU 缓存没有那么大——它只在该 CPU 使用数据时加载数据。
标签: java multithreading visibility shared-variable