Java 热点编译器是否会删除涉及已知最终状态的实例变量的死代码

问题描述 投票:0回答:1

在下面的代码中,很明显 baa 总是 false。热点编译器会发现这一点并删除 isBaa() 方法调用和包含的代码吗?

public class Foo() {
    public final boolean baa = false;
    public isBaa() {
        return baa;
    }
}

这样使用

static final Foo foo = new Foo();

public m() {
    if (foo.isBaa()) {
        // code here...
    }
}

我想知道这段代码是否与添加相比

static final Foo foo = new Foo();
static final BAA = foo.isBaa();

并检查

if (BAA) ...

对热点完成任务后的运行速度感兴趣。有没有办法实际看看热点编译的结果是什么?或者我们是否必须从正在使用的热点编译器的实现细节来推断。

用例是在对性能非常敏感的代码中通过最终变量来支持 isDebugEnabled()。所以我感兴趣的是方法调用本身是否被优化了。

java jvm-hotspot
1个回答
0
投票

回答我自己的问题...

我使用计时来测量热点何时完全摆脱代码。即,如果循环中的代码不再增加循环执行时间,则其已被编译出来。

  • 静态最终布尔检查可以完全编译出来。
  • 静态方法调用可以被编译出来。
  • 实例方法,即使标记为final,也不是。

在我对 ibm jdk8 最终方法调用的测试中,不执行任何操作大约需要 6 个时钟周期。

IBM 的 Hotspot 文档暗示最终实例方法可以内联,但测试表明仍然存在成本。我想未来的虚拟机可能能够进一步优化这一点。

在我的测试中,似乎热点编译也会影响循环在 CPU 核心之间的分布方式。

for(; i < Integer.MAX_VALUE ; i++)

神奇地在所有 4 个 CPU 上运行(平均时间为时钟周期的 1/4)

for(; i < Integer.MAX_VALUE ; i++) if (false) ...

平均需要1个时钟周期

因此,即使是热点编译的代码也不会影响周围代码的优化。

© www.soinside.com 2019 - 2024. All rights reserved.