【问题标题】:Java is using volatile keyword memory efficient?Java 使用 volatile 关键字内存效率高吗?
【发布时间】:2013-02-20 15:45:15
【问题描述】:

如果使用 1 个 volatile 变量,是否也会关闭其他相关非 volatile 变量的 cpu 缓存?

【问题讨论】:

  • 为什么像这样的微优化对任何人来说都很重要?我认为这与线程安全有关。

标签: java memory volatile memory-efficient


【解决方案1】:

不,它只会阻止该变量被加载到 cpu 缓存并在那里修改。更准确地说,它强制 CPU 在访问 volatile 字段后刷新其缓存。请参阅here 了解更多详细信息

【讨论】:

    【解决方案2】:

    它不会“关闭”缓存。但是是的,它确实通常会导致其他挂起写入的刷新(当您写入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 happens-before B 和 C happens-before D. 如果线程 2 中的 C 是 随后 中的 B线程 1,然后 B happens-before C,因此 A happens-before D.

    如果 A happens-before D 则写入 A 处 bar 的值必须在 D 处作为 bar 可用...假设在此期间没有其他内容写入 bar .

    这是具体实现的如何。但肯定会对缓存数据产生影响……包括非易失性字段的缓存副本。

    假设一个典型的内存架构,假设线程 1 和线程 2 不共享缓存,这意味着:

    • foobar 都必须由 B 处的线程 1 刷新到主内存,并且
    • 在 C 处,线程 2 的 foobar 的任何缓存副本都必须丢弃。

    我的理解是,这通常是使用缓存失效和缓存刷新指令来实现的。


    最重要的是,使用volatile 会对多核系统产生显着的性能影响,因为它会产生额外的内存流量。

    【讨论】:

      【解决方案3】:

      volatile 关键字与内存无关。这是一个并发问题。

      编辑 volatile 关键字与内存效率无关。这是一个并发问题。

      【讨论】:

      • 实际上确实与内存有关。特别是线程本地存储和 CPU 缓存
      • TLS!!您在哪里选择了 TLS 和 volatile 相关?
      • 也许你和我只是对效率这个词的定义不同,但我会更新我的帖子。
      • 写入 volatile 字段会将任何修改从您的 cpu 缓存刷新到主内存。这显然会对性能产生一些影响。
      • s/一些/可以忽略不计?同样如前所述,这不是我定义内存效率的方式。在我的世界观中,内存效率与空间有关,与性能无关。例如,HashMap 的内存效率低于 TreeMap,因为它(平均而言)使用更多内存来存储相同数量的数据。查找表的内存效率较低,因为它比实时执行算术使用更多的内存。它可能更快(因此计算效率更高)。
      猜你喜欢
      • 2016-02-12
      • 1970-01-01
      • 2012-05-31
      • 2012-09-22
      • 2023-03-21
      • 2011-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多