Sta*_*sky 130 java arrays jvm initialization java-7
根据JLS,int在初始化之后,应该用零填充数组.但是,我遇到的情况并非如此.这种行为首先发生在JDK 7u4中,也发生在所有后续更新中(我使用64位实现).以下代码抛出异常:
public static void main(String[] args) {
int[] a;
int n = 0;
for (int i = 0; i < 100000000; ++i) {
a = new int[10];
for (int f : a)
if (f != 0)
throw new RuntimeException("Array just after allocation: "+ Arrays.toString(a));
Arrays.fill(a, 0);
for (int j = 0; j < a.length; ++j)
a[j] = (n - j)*i;
for (int f : a)
n += f;
}
System.out.println(n);
}
Run Code Online (Sandbox Code Playgroud)
在JVM执行代码块的编译之后发生异常,并且不会出现-Xint标志.此外,该Arrays.fill(...)语句(与此代码中的所有其他语句一样)是必要的,如果不存在则不会发生异常.很明显,这个可能的错误与一些JVM优化有关.出于这种行为的原因有什么想法吗?
更新:
我在HotSpot 64位服务器VM上看到这种行为,在Gentoo Linux,Debian Linux(内核3.0版本)和MacOS Lion上从1.7.0_04到1.7.0_10的Java版本.始终可以使用上面的代码重现此错误.我没有使用32位JDK或Windows测试此问题.我已经向Oracle发送了一个错误报告(错误ID 7196857),它将在几天后出现在公共Oracle错误数据库中.
更新:
Oracle在其公共错误数据库中发布了此错误:http://bugs.sun.com/bugdatabase/view_bug.do?video_id = 7196857
Sta*_*sky 42
在这里,我们遇到了JIT编译器中的一个错误.编译器确定在分配后填充已分配的数组Arrays.fill(...),但是分配和填充之间的使用检查是错误的.因此,编译器执行非法优化 - 它会跳过已分配数组的归零.
此错误放在Oracle错误跟踪器中(错误ID 7196857).不幸的是,我没有等待甲骨文有关以下几点的任何澄清.正如我所看到的,这个错误是特定于操作系统的:它在64位Linux和Mac上完全可以重现,但是,正如我从评论中看到的那样,它在Windows上不经常复制(对于类似版本的JDK).另外,知道什么时候修复这个bug会很好.
目前只有建议:如果您依赖于新声明的数组的JLS,请不要使用JDK1.7.0_04或更高版本.
10月5日更新:
在2012年10月4日发布的JDK 7u10(早期访问)的新版本10中,至少对于Linux OS(我没有测试其他版本)修复了这个错误.感谢@Makoto,他发现Oracle错误数据库中的公共访问不再提供此错误.遗憾的是,我不知道Oracle将其从公共访问中删除的原因,但它可以在Google 缓存中使用.此外,这个bug引起了Redhat的注意:CVE标识符CVE-2012-4420 (bugzilla)和CVE-2012-4416(bugzilla)被分配给了这个漏洞.
| 归档时间: |
|
| 查看次数: |
6937 次 |
| 最近记录: |