假设我有同一个类的 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/