使用 Final 字段的成本

2024-03-14

我们知道,将字段设置为final通常是一个好主意,因为我们获得了线程安全性和不变性,这使得代码更容易推理。我很好奇是否有相关的性能成本。

Java 内存模型保证了这一点final Field Semantics http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5:

仅在对象完全初始化后才能看到对该对象的引用的线程保证看到该对象的最终字段的正确初始化值。

这意味着对于这样的课程

class X {
    X(int a) {
        this.a = a;
    }
    final int a;

    static X instance;
}   

每当线程 1 创建这样的实例时

X.instance = new X(43);
while (true) doSomethingEventuallyEvictingCache();

并且线程 2 看到了它

 while (X.instance == null) {
      doSomethingEventuallyEvictingCache();
 }
 System.out.println(X.instance.a);

它必须打印 43。没有final修改器、JIT 或 CPU 可以对存储重新排序(第一个存储X.instance然后设置a=43)并且线程 2 可以看到默认初始化值并打印 0。

当 JIT 看到final它显然避免重新排序。但它也必须强制CPU服从命令。是否存在相关的性能损失?


是否存在相关的性能损失?

如果你看一下JIT编译器的源代码,你会发现文件中关于final成员变量的以下注释src/share/vm/opto/parse1.cpp http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/812ed44725b8/src/share/vm/opto/parse1.cpp#l962:

这个方法(根据Java的规则必须是构造函数)写了一个final。在构造函数发布对新构造函数对象的引用之后,所有初始化的效果必须在任何代码之前提交到内存。我们不等待发布,而是简单地阻止此处的写入。我们不是只对那些需要完成的写入设置障碍,而是强制所有写入完成。

如果存在最终成员变量,编译器会发出附加指令。这些附加指令很可能会导致性能损失。但尚不清楚这种影响是否对任何应用程序都很重要。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Final 字段的成本 的相关文章

  • Selenium webdriver :列表不是通用的;它不能使用参数 `` 类型进行参数化

    我试图将链接存储在列表中 请按照以下代码操作 public class frameswitch public static void main String args System setProperty webdriver gecko d
  • WaitForSingleObject 是否充当内存屏障?

    昨天一个关于双重检查锁定的问题引发了一系列的想法 让我对一个简单的情况感到不确定 在下面的代码中 是否可以点击printf 不再同步 在这个简单的示例中 这些值可能位于同一缓存行上 因此我认为这种可能性较小 假设一开始可能性 gt 0 如果
  • RSA 加密-解密:BadPaddingException:数据必须以零开头

    对于一个被问了很多次的问题 我很抱歉向您询问您的技能 我有一个关于 RSA 加密的问题 我已经检查过有关此问题的其他主题 但没有找到任何有用的答案 我希望你能帮助我 我想读取一个文件 加密其内容 然后解密它并将这些解密的字节放入一个新文件中
  • 按对象值分组,统计后按最大对象属性设置组键

    我设法使用 Java 8 Streams API 编写了一个解决方案 该解决方案首先按对象 Route 的值对列表进行分组 然后计算每组中的对象数量 它返回一个映射 Route gt Long 这是代码 Map
  • 黄瓜与 Micronaut

    我正在尝试将 Cucumber 与 Micronaut 一起使用 但当我尝试将其与 Cucumber 一起使用时 MicronautTest 注释根本不起作用 未注入 theApple 请参阅下面的代码 如果我在没有黄瓜的情况下运行它就可以
  • PrintStream是有缓冲的,但是flush不会降低性能,而BufferedOutputStream会加速性能

    我预计由于 PrintStream 是缓冲的 通过在每次 print 之后添加刷新操作 速度性能应该会显着降低 但事实并非如此 如下面的代码片段所示 此外 将 PrintStream 包裹在 BufferedOutputStream 周围可
  • 为什么 MetaSpace 大小是已用 MetaSpace 的两倍?

    我写了一个程序来模拟MetaSpace OOM 但我发现MetaSpace Size几乎总是两倍大Used MetaSpace Why 我用标志运行我的程序 XX MaxMetaspaceSize 50m 程序抛出OOM时Used Meta
  • 将 emoji 替换为适当的 java 代码

    我正在开发一个简单的java程序 它可以接受这样的字符串 停止 你违反了 法律 但是现在 你 并将每个表情符号替换为适当的 java 字符 我不知道该怎么称呼他们 这是一个例子 汽车表情符号 将替换为 uD83D uDE97 这允许我有一个
  • 可以混合使用 JVM 语言吗?即:Groovy 和 Clojure

    我知道你可以轻松地混合groovy java clojure java 无论什么JvmLang java 这是否也意味着我也可以让 clojure 和 groovy 代码进行交互 如果我使用 Grails 或 jRoR 我也可以在该环境中使
  • Angularjs 在生产中禁用调试数据

    我正在尝试按照角度文档中的建议禁用生产服务器中的调试数据here https docs angularjs org guide production 补充一点 我并没有真正看到性能和加载时间有任何改进 这是我的代码在 app js 中的样子
  • 单线程公寓问题

    从我的主窗体中 我调用以下命令来打开一个新窗体 MyForm sth new MyForm sth show 一切都很好 但是这个表单有一个组合框 当我将其 AutoCompleteMode 切换为建议和追加时 我在显示表单时遇到了这个异常
  • 如何在 Ivy 中使用不同的分类器下载多个 Maven 依赖项?

    我试图依靠Neo4j 服务器 jar http repo neo4j org content repositories snapshots org neo4j app neo4j server 1 5 SNAPSHOT neo4j serv
  • EclipseLink 2.7.0 和 JPA API 2.2.0 - 签名不匹配

    当运行由maven构建的具有以下依赖项的项目时
  • 为什么jdk中没有ConcurrentLinkedHashMap类?

    这个问题直接接着问从我之前的问题来看 https stackoverflow com q 12299731 1527084 我想我的第二个问题的答案是否定的 所以我想了解为什么 java util concurrent 包中没有 Concu
  • Jupyter Notebook 中的多处理与线程

    我试图测试这个例子here https ipywidgets readthedocs io en stable examples Widget 20Asynchronous html将其从线程更改为多处理 在 jupyter Noteboo
  • 如何将多部分文件从另一个服务发送到一个服务

    我有两个端点 api 它们是 uploadand 重定向 upload是我直接上传文件的地方 重定向是我接收文件并将其传递给上传并获取 JSON 响应的地方 upload 所以下面是我的代码 package com example impo
  • Android应用程序中的模式输入

    我想知道是否有其他替代方案可以替代 Android 上平庸的 EditText 密码输入 是否有 API 或开源代码可以集成到我的应用程序中 类似于锁屏图案解锁 Intent 可能会返回哈希值 数字 字符串或代表用户输入的模式的任何内容 我
  • 如何确保超类的子类方法的线程安全?

    我参加了一次面试 并被要求为以下要求设计一个课程 假设我有一个 A 类 它可以有任意数量的子类 即子类 类 A 有一个名为 doSomething 的方法 该方法是同步的 要求是 A 的所有子类都是强制性的重写 doSomething me
  • RecyclerView 适配器的 Kotlin 泛型

    我正在尝试编写一个通用的 recyclerview 适配器 我找到了几个例子 然而 仍然无法弄清楚如何实现通用适配器 我写的代码是 open abstract class BaseAdapter
  • 按字母顺序对对象的 ArrayList 进行排序

    我必须创建一个方法来排序数组列表根据电子邮件按字母顺序排列对象 然后打印排序后的数组 我在排序时遇到麻烦的部分 我已经研究过并尝试使用Collections sort vehiclearray 但这对我不起作用 我是因为我需要一个叫做比较器

随机推荐