几天前,我提出了一个问题,询问如何使用关键字'volatile',我得到了答案。在此,我再次感谢帮助我的人们。 然而,一个关于JMM的新问题在我脑海中浮现,目前我知道有主内存和线程拥有独立的缓存(可能还有更专业的术语),现在我想知道线程缓存中存储的是什么,共享对象引用的副本(对象地址的副本)或共享对象的副本?例如,我声明一个对象B b = new B();并且b可以通过两个线程访问,然后当线程访问b时,对象引用 b被复制并存储在线程自己的缓存内存中,或者是对象,其中b指向被复制并存储在线程自己的缓存中?感谢。
答案 0 :(得分:3)
多个线程访问的任何内容都可以在“线程缓存”中。如果它们是对象的一部分,则包括引用。它不包含局部变量中的引用,因为它们位于堆栈中,无法从其他线程访问。
所以答案真的是“两个”。
答案 1 :(得分:0)
变量b
是对象的引用,它存储在堆上。
答案 2 :(得分: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如何访问和写入内存可能是一个令人惊讶的复杂主题,因为它会对性能产生很大影响。