请看一下这段代码:
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 选项后,观察到以下结果:
此代码的最小总内存大小应至少为 1024m,否则会出现 OutOfMemoryError。 -Xms 选项影响 for
block 的执行时间:
对于 -Xms16m,它的流动时间为 10 秒;对于 -Xms256m,它的流动时间为 4 秒。
问题是 - 为什么初始可用内存大小会影响每次迭代而不仅仅是第一次迭代?
提前谢谢您。
最佳答案
Java 中的微基准测试并不是那么简单。当我们运行java程序时,很多事情都是在后台发生的;垃圾收集就是一个典型的例子。还可能存在从 Java 进程到另一个进程的上下文切换的情况。 IMO,没有明确的解释为什么在看似随机的时间中会产生一个序列。
关于java - Java VM奇怪的性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5603742/