java - 现代 JVM 可以不同地优化同一类的不同实例吗?

标签 java optimization jvm bytecode jvm-hotspot

假设我有同一个类的 2 个实例,但它们的行为不同(遵循不同的代码路径)基于构造时设置的最终 boolean 字段。所以像这样:

public class Foo {
   private final boolean flag;

   public Foo(boolean flagValue) {
      this.flag = flagValue;
   }

   public void f() {
      if (flag) {
         doSomething();
      } else {
         doSomethingElse();
      }
   }
}

具有不同 flag 值的 Foo 的 2 个实例在理论上可以由 2 个不同的程序集支持,从而消除了 if 的成本(对于人为的例子,抱歉,这是我能想出的最简单的一个)。

所以我的问题是 - 有任何 JVM 真的这样做吗?还是单个类总是由单个程序集支持?

最佳答案

是的,JVM 会进行这种形式的优化。在您的情况下,这将是 inlining and adaptive optimization 的结果因为值(value)永远是真实的。考虑以下代码:

Foo foo = new Foo(true);
foo.f();

为 HotSpot 证明 Foo 始终是 f 的调用站点上的 Foo 的实际实例是微不足道的,这允许 VM简单地复制粘贴方法的代码,从而消除虚拟分派(dispatch)。内联后,示例简化为:

Foo foo = new Foo(true);
if (foo.flag) {
  doSomething();
} else {
  doSomethingElse();
}

这又一次允许将代码减少为:

Foo foo = new Foo(true);
foo.doSomething();

因此,是否可以应用优化取决于 foo 调用站点的单态性和该调用站点上 flag 的稳定性。 (VM 为此类模式分析您的方法。)VM 预测程序结果的能力越低,应用的优化就越少。

如果示例像上面的代码一样简单,JIT 可能还会删除对象分配并简单地调用 doSomething。此外,对于字段值可以被简单地证明为 true 的简单示例情况,VM 甚至不需要自适应优化,而只是应用上述优化。有一个很棒的工具,名为 JITWatch这使您可以查看您的代码是如何优化的。

关于java - 现代 JVM 可以不同地优化同一类的不同实例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40493917/

相关文章:

javascript - Kotlin - 多平台功能

java - 在Windows机器上比较两个json文件

java - 无法应用渲染

c++ - 处理指针时,C++ 编译器可以优化掉代码吗?

optimization - Rust 编译器对 `loop` 和 `while true` 做了哪些优化?

tomcat - Excelsior jet 编译的 apache tomcat 服务器是否可作为开源项目的一部分重新分发?

java - 跨多个线程/节点的 session 管理

java - JBoss JAAS 自定义登录模块错误消息

c - 使用 SSE Intrinsics 计算长度和差异的浮点 x、y、z 数组上的循环向量化

java - 为什么 HotSpots 编译日志时间与 ManagementFactory.getRuntimeMXBean().getUptime() 不同?