Java 为什么JIT不能消除我的死代码

Java 为什么JIT不能消除我的死代码,java,jit,jmh,Java,Jit,Jmh,我写了两个基准测试来证明JIT在编写好的基准测试时可能会有问题(请跳过我在这里没有使用@State): 我认为JIT将消除死代码,因此将同时执行两个方法。但最后,我有: 四位数0.158±0.046的汇总统计标准偏差 死区码陷波器.数字0.359±0.294的汇总统计值\u标准偏差 为什么JIT没有优化它?summaryStatistics.getStandardDeviation()的结果不在方法之外的任何地方使用,也不由方法返回 (我使用的是OpenJDK build 10.0.2+13-U

我写了两个基准测试来证明JIT在编写好的基准测试时可能会有问题(请跳过我在这里没有使用@State):

我认为JIT将消除死代码,因此将同时执行两个方法。但最后,我有:

四位数0.158±0.046的汇总统计标准偏差 死区码陷波器.数字0.359±0.294的汇总统计值\u标准偏差


为什么JIT没有优化它?
summaryStatistics.getStandardDeviation()的结果
不在方法之外的任何地方使用,也不由方法返回


(我使用的是OpenJDK build 10.0.2+13-Ubuntu-1ubuntu0.18.04.4)

如果你说的是Apache Commons数学类,那么它是一个庞大的类。它的构造肯定不会内联。要了解原因,请使用
-XX:+UnlockDiagnosticVMOptions-XX:+PrintInline-XX:-BackgroundCompilation运行

死代码消除发生在内联之后。 未使用的对象将反向传播,但非内联构造函数将断开链,因为JIT优化器无法再确保没有副作用


换句话说,您希望删除的代码太大。

什么代码死在这里?您是否希望两个代码占用相同的时间?您具体期望什么?我对这个结果一点也不感到惊讶
summaryStatistics.getStandardDiversion()
未在方法范围之外的任何地方使用或返回,因此在JIT优化后保留该代码没有意义?或者它会保留它,因为它无法决定这个代码是否有任何副作用?是的,你是对的。首先,我想使用
java.util
中的
DoubleSummaryStatistics
,但我搞砸了导入。在
DoubleSummaryStatistics
情况下,它是内联的,与空方法的结果几乎相同。谢谢
@Fork(value = 1)
@Warmup(iterations = 2, time = 10)
@Measurement(iterations = 3, time = 2)
@BenchmarkMode(Mode.AverageTime)
public class DeadCodeTraps {

    @Benchmark
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    public static void summaryStatistics_standardDeviationForFourNumbers() {
        final SummaryStatistics summaryStatistics = new SummaryStatistics();
        summaryStatistics.addValue(10.0);
        summaryStatistics.addValue(20.0);
        summaryStatistics.addValue(30.0);
        summaryStatistics.addValue(40.0);
        summaryStatistics.getStandardDeviation();
    }

    @Benchmark
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    public static void summaryStatistics_standardDeviationForTenNumbers() {
        final SummaryStatistics summaryStatistics = new SummaryStatistics();
        summaryStatistics.addValue(10.0);
        summaryStatistics.addValue(20.0);
        summaryStatistics.addValue(30.0);
        summaryStatistics.addValue(40.0);
        summaryStatistics.addValue(50.0);
        summaryStatistics.addValue(60.0);
        summaryStatistics.addValue(70.0);
        summaryStatistics.addValue(80.0);
        summaryStatistics.addValue(90.0);
        summaryStatistics.addValue(100.0);
        summaryStatistics.getStandardDeviation();
    }

}