Java: int array initializes with nonzero elements
According to the JLS, an int
array should be filled by zeros just after initialization. However, I am faced with a situation where it is not. Such a behavior occurs first in JDK 7u4 and also occurs in all later updates (I use 64-bit implementation). The following code throws exception:
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);
}
The exception occurs after the JVM performs compilation of the code block and does not arise with -Xint
flag. Additionally, the Arrays.fill(...)
statement (as all other statements in this code) is necessary, and the exception does not occurs if it is absent. It is clear that this possible bug is bounded with some JVM optimization. Any ideas for the reason of such a behavior?
Update:
I see this behavior on HotSpot 64-bit server VM, Java version from 1.7.0_04 to 1.7.0_10 on Gentoo Linux, Debian Linux (both kernel 3.0 version) and MacOS Lion. This error can always be reproduced with the code above. I did not test this problem with a 32-bit JDK or on Windows. I already sent a bug report to the Oracle (bug id 7196857) and it will appear in public Oracle bug database in few days.
Update:
Oracle published this bug at their public bug database: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7196857
Here we are faced with a bug in the JIT-compiler. Compiler determines that the allocated array is filled after allocation in Arrays.fill(...)
, but the check for uses between the allocation and the fill is faulty. So, compiler performs an illegal optimization - it skips zeroing of allocated array.
This bug is placed in Oracle bug tracker (bug id 7196857). Unfortunately, I did not wait for any clarifications from Oracle about the following points. As I see, this bug is OS-specific: it absolutely reproducible on 64-bit Linux and Mac, but, as I see from comments, it reproduces not regularly on Windows (for similar versions of JDK). Additionally it would be nice to know when this bug will be fixed.
There is only advice at the moment: do not use JDK1.7.0_04 or later if you depend on JLS for newly declared arrays.
Update at October 5:
In the new Build 10 of the JDK 7u10 (early access) released at October 04, 2012, this bug was fixed at least for Linux OS (I did not test for other). Thanks to @Makoto, who found that this bug is no longer available for public access in Oracle bug database. Unfortunately, I do not know for the reasons Oracle removed it from public access, but it is available in Google cache. Also, this bug has caught the attention of Redhat: the CVE identifiers CVE-2012-4420 (bugzilla) and CVE-2012-4416 (bugzilla) were assigned to this flaw.