Java 中的错误 for 循环?
我观察到运行以下 java 代码时出现错误行为:
public class Prototype {
public static void main(String[] args) {
final int start = Integer.MAX_VALUE/2;
final int end = Integer.MAX_VALUE;
{
long b = 0;
for (int i = start; i < end; i++) {
b++;
}
System.out.println(b);
}
{
long b = 0;
for (int i = start; i < end; i++) {
b++;
}
System.out.println(b);
}
}
}
两个循环的作用完全相同。然而,第二个输出一个不确定的错误值。我正在 Linux 上运行代码,使用版本:
java version "1.6.0_25"
Java(TM) SE Runtime Environment (build 1.6.0_25-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.0-b11, mixed mode)
示例输出:
1073741811
141312
你能重现它吗?这是一个错误吗?
编辑:奇怪的
final int end = Integer.MAX_VALUE - 1;
作品很好。
I observed erroneous behaviour running the following java-code:
public class Prototype {
public static void main(String[] args) {
final int start = Integer.MAX_VALUE/2;
final int end = Integer.MAX_VALUE;
{
long b = 0;
for (int i = start; i < end; i++) {
b++;
}
System.out.println(b);
}
{
long b = 0;
for (int i = start; i < end; i++) {
b++;
}
System.out.println(b);
}
}
}
Both loops do exactly the same. Nevertheless, the second one outputs a non-deterministic erroneous value. I'm running the code on Linux using Version:
java version "1.6.0_25"
Java(TM) SE Runtime Environment (build 1.6.0_25-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.0-b11, mixed mode)
Sample Output:
1073741811
141312
Can you reproduce it? Is it a bug?
Edit: Strange
final int end = Integer.MAX_VALUE - 1;
works fine.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我可以使用 Eclipse 生成的
.class
文件重现它,但在使用javac
在命令行上编译时却无法重现它。生成的字节码有所不同:
javac
输出为了便于阅读,这里是 Soot:
Eclipse 编译器输出
Grimp 输出:
有趣的是,
javac
生成的版本使用if_icmpge
作为退出条件(>= 2147483647) 在一个int
上,这应该没有意义(等于,但大于)。不过,两者看起来都是正确的,所以我怀疑存在 JVM 错误。I'm able to reproduce it with the
.class
file produced by Eclipse, but not when compiling on the command line withjavac
.The bytecode generated differs:
javac
outputFor something easier to read, here is the Grimp output produced by Soot:
Eclipse compiler output
Grimp output:
Interestingly, the
javac
-produced version usesif_icmpge
as an exit condition (>= 2147483647) on anint
, which shouldn't make sense (the equal does, but not the greater than). Both look correct, though, so I'd suspect a JVM bug.有些错误会影响 for 循环,特别是当上限接近
Integer.MAX_VALUE
时。请参阅此问题。
There are bugs that affect for loops specifically when the upper bound is close to
Integer.MAX_VALUE
.See this question.
根据 Java 专家的说法,这是 bug 5091921,已在 JDK7 中修复,但未计划JDK6 中的修复。
According to the Java gurus this is bug 5091921, fixed in JDK7 but not planned for a fix in JDK6.
这可能是 64 位服务器 VM 中 HotSpot 中展开的错误循环。尝试使用
-client
或+XX:-AggressiveOpts
运行代码。It is possible it is the erroneous loop unrolling in HotSpot in 64-bit server VM. Try running the code with either
-client
or+XX:-AggressiveOpts
.