0

几天前,我提出了一个问题,询问如何使用关键字'volatile',我得到了答案。在此我要再次感谢帮助过我的人。然而,一个关于JMM的新问题出现在我的脑海中,目前我知道有主内存和线程自己独立的缓存(可能有更专业的术语),现在我想知道线程缓存中存储了什么,共享对象引用的副本(对象地址的副本)还是共享对象的副本?例如,我声明一个对象 B b = new B(); b 可以被两个线程访问,那么当线程访问 b 时,是对象引用b 被复制并存储在线程自己的缓存中还是 b 指向的对象被复制并存储在线程自己的缓存中?谢谢。

4

3 回答 3

3

任何被多个线程访问的东西都可能在“线程缓存”中。如果它们是对象的一部分,则包括引用。它不包括保存在局部变量中的引用,因为它们在堆栈上并且不能从其他线程访问。

所以答案真的是“两者”。

于 2011-05-03T04:43:44.020 回答
0

变量b是对存储在堆上的对象的引用。

于 2011-05-03T04:02:10.760 回答
0

通常,您不需要知道引用存储的时间或位置。内存不仅仅是两层的,它比这复杂得多。从上到下你都有。

registers
L1 cache
L2 cache
L3 cache
local main memory
nonlocal main memory
swap space.

本地主内存是 CPU 的本地内存。您可以拥有另一个 CPU 的本地内存。所以要执行

B b = new B();

它必须分配一些通常来自 TLAB(线程本地分配缓冲区)的内存,该内存空间通常位于 L1 到本地主内存之间。可以有所有级别的副本。但是,引用必须在寄存器中,以便可以将其分配给局部变量。它可能会保存到堆栈和内存中,也可能不会。

即使在 CPU 中,“寄存器”也是一个广泛的类别。CPU 如何访问和写入内存可能是一个令人惊讶的复杂主题,因为它会对性能产生重大影响。

于 2011-05-03T07:33:08.820 回答