【问题标题】:java final variables and performance [duplicate]java最终变量和性能[重复]
【发布时间】:2015-08-12 00:36:16
【问题描述】:

如果 java 代码中的 final 变量过饱和,这很好吗?我考虑性能。据我所知,最终变量是线程安全的。因此,对于最终变量 jvm 的每次初始化,必须在所有线程之间同步其值。如果我在希望变量不可修改的每种情况下都使用最终变量,它会影响性能吗?

我预计并担心最终变量会降低性能。

【问题讨论】:

  • 您可能想看看this。简而言之:最终的引用是线程安全的,而对象本身不是。
  • 我知道 final 变量是线程安全的!这就是为什么我期望并害怕性能下降

标签: java multithreading performance


【解决方案1】:

最终变量背后没有性能原因。您可以通过使用不可变对象来获得性能,因为在这种情况下,java 可以避免 GC 在这些对象上运行。即使一个字段是最终的,你只是说你不移动指向这个对象的指针的几个字节,它对性能没有影响,因为你仍然可以修改这个对象的字段。提高性能(通过减少 GC 开销)的唯一方法是尽可能使用不可变对象。但是你需要保持理性,而不是以降低代码可读性为代价强迫一切都不可篡改。

【讨论】:

  • 相反,我可以只使用可变对象来提高性能
  • 是的,这几乎就像一个问题,用玻璃杯喝水是最好的方法,还是应该用水龙头喝?理论上,如果 java 可以避免 GC 运行,那么您的应用程序将拥有更多 CPU,这应该会提高性能。但是总有但是……一些特殊情况……一些 JVM 设计,一些 GC 设计……这一切都可能会有所不同
【解决方案2】:

final 变量没有性能问题。

如果您想在多线程环境中使用变量而不是使用 final 变量,请使用 Volatile 变量。

易失性变量是线程安全的。 Java 中的 volatile 关键字保证 volatile 变量的值总是从主内存中读取,而不是从 Thread 的本地缓存中读取。

【讨论】:

  • 我有点不同意这一点 - 易失性变量是线程安全的。 ??是的,您的下一行解释了 volatile 的使用。但我们仍然需要同步。
  • 我们只对方法使用同步。我们不能对变量使用相同的。如果多个线程正在访问变量,则数据将被损坏。为了克服这个问题,引入了可变变量。
  • Volatile variables 只是告诉 jvm “不要缓存变量的状态,而是将其直接刷新到内存,但它不为 threadSafety 提供任何语义。”它提供了一种较弱的同步形式。假设你有一个长变量 a(64 位)并且你做了一个赋值 b = a。然后它作为两步过程的一部分发生,使其仅易失性不会阻止它。只有同步才有帮助。
  • 接受!!!我想知道“我们如何实现变量同步?”
  • :)。当我说我们需要在访问这些变量时使用同步。这意味着我们必须在同步块中访问这些共享变量。
【解决方案3】:

我明白你的意思。一般来说,具有最终字段的类是线程安全的,因为您不能编写直接在运行时修改这些字段的代码。因此,没有任何其他线程可以意外地修改此类不可变类的实例。 现在,关于成本。没有特定的 java 字节码来读取/写入最终字段。此外,您可以通过反射、JNI 调用、生成的字节码(“正常”构造函数路径除外)更改任何最终字段。这意味着最终字段实际上并不是最终的,它们似乎只是一个编译时间限制,一种语法糖。但是,final 字段的一个特定方面可能会影响性能,因为 JMM 为它们定义了特定的语义(通常是专业成本,不是吗?:)):http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5 它为包含最终字段的构造函数定义了合成同步操作“冻结操作”。该动作是“冻结动作 - 读取所创建对象的引用” HB 边缘的一部分,它真正保证所有线程都能看到正确初始化的最终字段。但是我们看到,在现实生活中,冻结和非冻结构造函数之间没有任何显着差异:http://shipilev.net/blog/2014/all-fields-are-final/

因此,底线是最终字段的成本几乎与非最终字段相同。局部最终变量是纯语法糖,与非最终局部变量相比没有任何成本。

最后,如果你开发一个高性能/低延迟的应用程序,不要在它的主路径中使用不可变对象(不要一直分配内存),使用可变对象(带有缓冲区、池等),因为通常即使是空的构造函数也会花费大约 30ns + 次要 GC 也不是免费的 + 在密集内存(重新)分配的情况下缓存局部性最差......

【讨论】:

  • 酷,将 JMM 最终语义扩展到所有字段会非常好。
猜你喜欢
  • 2020-04-23
  • 1970-01-01
  • 2015-06-04
  • 2011-11-25
  • 2018-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-16
相关资源
最近更新 更多