java - Java VM奇怪的性能问题

标签 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 选项后,观察到以下结果:

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

对于 -Xms16m,它的流动时间为 10 秒;对于 -Xms256m,它的流动时间为 4 秒

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

提前谢谢您。

最佳答案

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

关于java - Java VM奇怪的性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5603742/

相关文章:

java - 为什么从匿名内部类访问时要求局部变量是最终的?

java - 更改对象字段中的变量值

java - 在 64 位 Java 中使用 long 而不是 int 有好处吗

c# - 以高性能方式审核和验证对 C# 类和结构属性的更改

java - 为什么 MAIN 和 LAUNCHER Activity 不是首先开始?

java - 或者 if block 中的条件仅检查第一个 stmt 但不检查第二个 stmt

python - 映射单个函数比两次映射两个单独的函数慢?

c - 在 C 中的字符串中搜索最有效的内存方式

java - 更改已填充菜单的背景

c++ - 为什么我的性能计数器代码不起作用?