Java VM的奇怪性能问题

时间:2011-04-09 08:11:01

标签: java performance

请看这段代码:

public static void main(String[] args) {
    String[] array = new String[10000000];
    Arrays.fill(array, "Test");
    long startNoSize;
    long finishNoSize;
    long startSize;
    long finishSize;
    for (int called = 0; called < 6; called++) {
        startNoSize = Calendar.getInstance().getTimeInMillis();
        for (int i = 0; i < array.length; i++) {
            array[i] = String.valueOf(i);
        }
        finishNoSize = Calendar.getInstance().getTimeInMillis();
        System.out.println(finishNoSize - startNoSize);
    }
    System.out.println("Length saved");
    int length = array.length;
    for (int called = 0; called < 6; called++) {
        startSize = Calendar.getInstance().getTimeInMillis();
        for (int i = 0; i < length; i++) {
            array[i] = String.valueOf(i);
        }
        finishSize = Calendar.getInstance().getTimeInMillis();
        System.out.println(finishSize - startSize);
    }
}

执行结果因运行而异,但可以观察到一种奇怪的行为:

6510
4604
8805
6070
5128
8961
Length saved
6117
5194
8814
6380
8893
3982

通常,有3个结果: 6秒 4秒 8秒,它们以相同的顺序迭代。

谁知道,为什么会这样?

更新

在使用-Xms和-Xmx Java VM选项后,观察到下一个结果:

此代码的最小总内存大小应至少为1024米,否则会出现OutOfMemoryError。 -Xms选项影响for块的执行时间:

对于-Xms16m,它在 10秒之间流动,对于-Xms256m在 4秒之间流动。

问题是 - 为什么初始可用内存大小会影响每次迭代而不仅影响第一次?

提前谢谢。

2 个答案:

答案 0 :(得分:2)

Java中的微基准测试并不是那么简单。当我们运行java程序时,后台会发生很多事情;垃圾收集是一个很好的例子。也可能存在从Java进程到另一个进程的上下文切换的情况。 IMO,没有明确的解释为什么在看似随机的时间内产生了一个序列。

答案 1 :(得分:1)

这并非完全出乎意料。有各种因素可能会影响您的数字。

请参阅:How do I write a correct micro-benchmark in Java?