java编译器可以消除以下场景中的死代码吗?

时间:2014-04-14 19:35:25

标签: compiler-construction javac dead-code

(问题#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
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

javac(至少来自OpenJDK)不会消除死代码,除了用于模仿其他语言的编译时常量分支'条件编译(参见this JLS section末尾的例子)。

但是,优化JVM非常智能。 HotSpot(OpenJDK JIT)可能会也可能不会在此代码中传播o != null约束,但它会通过概要分析注意到内部o == null测试永远不会成立,并避免为该分支发出代码(将其转换为进入一个不寻常的陷阱)。并且始终被观察为false的空检查非常便宜,因为它们被折叠成加载指令,使用segfaults来检查null;如果看到null,JVM将查看错误指令地址以从正确的位置抛出NullPointerException,并将deoptimize到显式分支。 (查看有关HotSpot性能技巧here的更多信息。)因此,即使它没有传播路径约束,它也会有效地删除该分支。

如果你担心运行时性能,你根本不应该担心这一点,特别是在没有表明问题的分析信息的情况下。

如果您只想要小型.class文件,您应该使用像ProGuard这样的优化器,但我不知道它是否具有优化此特定模式所需的数据流分析。