为什么第一个方法调用总是花费最长时间?

时间:2017-02-11 01:16:02

标签: java time jvm system

在阅读Stack Overflow上的类似主题后,我编写了以下代码,以了解System.nanoTime()的一致性。

它只是在方法调用空void函数之前和之后调用System.nanoTime(),记录过程中经过的时间。但是,正如您在结果中看到的那样,第一次调用总是花费最长的时间。这是什么原因?

public class Test {
    public static void main(String[] args) {
        for(int i = 0; i < 10; i++) {
            double start = System.nanoTime();
            foo();
            double end = System.nanoTime();
            double diff = end - start;
            System.out.println("Diff: " + diff);
        }
    }

    public static void foo() {

    }
}

结果:

Diff: 2765.0
Diff: 509.0
Diff: 236.0
Diff: 238.0
Diff: 230.0
Diff: 539.0
Diff: 359.0
Diff: 356.0
Diff: 380.0
Diff: 353.0

请注意,我确实已阅读此问题:Why does first call to java.io.File.createTempFile(String,String,File) take 5 seconds on Citrix?

此外,此链接有助于将来参考,但不一定能回答我的具体问题:How do I write a correct micro-benchmark in Java?

1 个答案:

答案 0 :(得分:3)

JVM懒洋洋地执行类解析(请参阅JVMS 5.4.3)。在您的情况下,常量池中foo的符号引用在第一次执行invokestatic字节码时解析,即在方法的第一次调用时解析。显然,它比执行已经解析的字节码需要更多的时间。