Java使用volatile关键字的内存效率如何?
如果使用1个易失性变量,它是否也会关闭其他相关非易失性变量的cpu缓存?否,它只会阻止该变量加载到cpu缓存并在那里修改。更准确地说,它强制cpu在访问volatile字段后刷新其缓存。请参阅,以了解更多投诉详细信息它不会“关闭”缓存。但是是的,它通常会导致其他挂起写入的刷新(当您写入Java使用volatile关键字的内存效率如何?,java,memory,volatile,memory-efficient,Java,Memory,Volatile,Memory Efficient,如果使用1个易失性变量,它是否也会关闭其他相关非易失性变量的cpu缓存?否,它只会阻止该变量加载到cpu缓存并在那里修改。更准确地说,它强制cpu在访问volatile字段后刷新其缓存。请参阅,以了解更多投诉详细信息它不会“关闭”缓存。但是是的,它通常会导致其他挂起写入的刷新(当您写入volatile时)或至少一些缓存失效(当您读取volatile时)。。。这两种方法都会占用额外的内存带宽,并且会影响性能 考虑这个例子: public volatile int foo; public int b
volatile
时)或至少一些缓存失效(当您读取volatile
时)。。。这两种方法都会占用额外的内存带宽,并且会影响性能
考虑这个例子:
public volatile int foo;
public int bar;
/* thread 1 */
bar = 1; // A
foo = 1; // B
/* thread 2 */
System.err.println("foo = " + foo); // C
System.err.println("bar = " + bar); // D
JLS说A发生在B之前,C发生在D之前。如果线程2中的C在线程1中的B之后,那么B发生在C之前,因此A发生在D之前
如果A发生在D之前,则写入A处的bar
的值必须作为bar
在D处可用。。。假设在此期间没有任何其他内容写入条
具体如何实现这一点取决于具体的实现。但缓存数据肯定会受到影响。。。包括非易失性字段的缓存副本
假设是典型的内存体系结构,并且假设线程1和线程2不共享缓存,这意味着:
- 必须通过B处的线程1将
和foo
刷新到主内存,并且bar
- 在C处,必须丢弃线程2缓存的
和foo
的任何副本bar
归根结底,使用volatile会对多核系统产生显著的性能影响,因为它会产生额外的内存流量。volatile关键字与内存无关。这是一个并发问题 编辑
volatile关键字与内存效率无关。这是一个并发问题。为什么像这样的微优化对任何人都很重要?我以为这与线程安全有关,实际上它与内存有关。特别是线程本地存储和cpu cachingTLS!!你从哪里知道TLS和volatile是相关的?也许你和我只是对单词efficiency有不同的定义,但我会更新我的帖子。写入volatile字段会将任何修改从cpu缓存刷新到主内存。这显然会对性能产生一些影响。s/some/可忽略不计?同样如前所述,这不是我定义内存效率的方式。在我看来,内存效率与空间有关,而与性能无关。例如,HashMap的内存效率低于TreeMap,因为它(平均)使用更多内存来存储相同数量的数据。查找表的内存效率较低,因为它比实时执行算术占用更多内存。它可能更快(因此计算效率更高)。