(问题#0:java编译器默认情况下会消除死代码吗?)
问题1:假设我有下面的一段代码(它是人工生成的,所以我没有太多的控制权),编译器能为我消除死代码吗?
static void foo(final Object o)
{
if (o == null) {
// do something
}
else {
// do something
if (o == null) { // this condition is never gonna be true
// do something
}
else {
// do something
}
}
}
javac
(至少来自OpenJDK)并没有消除死代码,除了用于模拟其他语言的条件编译的编译时常数分支(请参阅本JLS部分末尾的示例)。
然而,优化JVM是非常明智的。HotSpot(OpenJDK JIT)可能会也可能不会在该代码中传播o != null
约束,但它会通过分析注意到内部o == null
测试从来都不是真的,并避免发出该分支的代码(将其变成一个不常见的陷阱)。一直被认为是错误的null检查非常便宜,因为它们被折叠到加载指令中,使用segfault来检查null;如果看到null,JVM将查看出错的指令地址,从正确的位置抛出NullPointerException,并将去优化为显式分支。(请在此处查看有关HotSpot性能技巧的更多信息。)因此,即使它不传播路径约束,它也会有效地删除该分支。
如果您关心运行时性能,那么根本不应该担心这一点,尤其是在没有表示问题的分析信息的情况下。
如果你只想要小的.class文件,你应该使用像ProGuard这样的优化器,尽管我不知道它是否具有优化这个特定模式所需的数据流分析。