这是JVM错误还是"预期行为"?

Mic*_*wan 70 java jvm integer-overflow compiler-optimization

我注意到了一些意想不到的行为(意外相对于我的个人期望),我想知道是否有什么东西,如果JVM中有一个错误,或者这可能是一个边缘情况,我不明白究竟是什么细节应该发生.假设我们在main方法中有以下代码:

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

一个天真的期望是,这将打印Integer.MAX_VALUE-1,最大甚至可表示int.但是,我认为整数算术应该在Java中"翻转",因此Integer.MAX_VALUE应该导致添加1 Integer.MIN_VALUE.由于Integer.MIN_VALUE仍然小于Integer.MAX_VALUE,循环将继续迭代负甚至整数.最终它会回到0,这个过程应该重复为无限循环.

当我实际运行此代码时,我得到非确定性结果.打印的结果往往大约为50万,但确切的值会有所不同.因此,当我认为它应该是一个无限循环时,不仅循环终止,而且它似乎随机终止.这是怎么回事?

我的猜测是,这可能是JVM中的一个错误,或者正在进行大量的时髦优化,这会产生这种预期的行为.这是什么?

Kev*_*ion 48

已知错误.相关

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

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

和别的.

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


Jon*_*eet 15

这很奇怪.它当然看起来像一个错误.每次使用相同的代码我都会得到相同的结果,但代码的微小变化会改变结果.例如:

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

...总是打印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);
  }
}
Run Code Online (Sandbox Code Playgroud)

总是打印-2147483648和true.

非常非常奇怪.

(那是在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)
Run Code Online (Sandbox Code Playgroud)