这是 JVM 错误还是“预期行为”?

我注意到一些意想不到的行为(相对于我个人的期望来说出乎意料),我想知道JVM中是否存在错误,或者这是否是一个边缘情况,我不明白究竟应该发生什么的一些细节。假设我们自己在 main 方法中有以下代码:

int i;
int count = 0;
for(i=0; i < Integer.MAX_VALUE; i+=2){
  count++;
}
System.out.println(i++);

一个天真的期望是,这将打印,最大的甚至可代表的。但是,我相信整数算术应该在Java中“翻转”,因此将1添加到应该会导致.由于 仍然小于 ,循环会不断迭代负整数。最终它将返回到 0,并且此过程应作为无限循环重复。Integer.MAX_VALUE-1intInteger.MAX_VALUEInteger.MIN_VALUEInteger.MIN_VALUEInteger.MAX_VALUE

当我实际运行此代码时,我得到非确定性结果。打印的结果往往在五十万左右,但确切的值各不相同。因此,当我认为循环应该是一个无限循环时,它不仅终止了,而且它似乎是随机终止的。这是怎么回事?

我的猜测是,这要么是JVM中的一个错误,要么是有很多时髦的优化正在进行,这使得这种预期的行为。这是什么?


答案 1

已知错误。相关

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6196102

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6357214

和其他人。

我认为它们被认为是低优先级的修复,因为它们不会出现在现实世界中。


答案 2

这很奇怪。它当然看起来像某个地方的错误。每次使用相同的代码时,我都会得到相同的结果,但对代码的微小更改会更改结果。例如:

public class Test {
  public static void main(String[] args) {
    int i;
    int count = 0;
    for (i = 0; i < Integer.MAX_VALUE; i+=2) {
      count++;
    }
    System.out.println(i);
    System.out.println(i < Integer.MAX_VALUE);
  }
}

...始终打印2147483640且真实

而这:

public class Test {
  public static void main(String[] args) {
    int i;
    for (i = 0; i < Integer.MAX_VALUE; i+=2) {
    }
    System.out.println(i);
    System.out.println(i < Integer.MAX_VALUE);
  }
}

始终打印 -2147483648和真实。

非常非常奇怪。

(这是在Linux上运行OpenJDK 1.6 VM。

编辑:在Windows 7上运行OpenJDK 1.7,我没有看到问题:

java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b78)
Java HotSpot(TM) Client VM (build 17.0-b05, mixed mode, sharing)

推荐