Zgodnie z JLS int
zaraz po inicjalizacji tablica powinna zostać wypełniona zerami. Jednak mam do czynienia z sytuacją, w której tak nie jest. Takie zachowanie pojawia się najpierw w JDK 7u4, a także we wszystkich późniejszych aktualizacjach (używam implementacji 64-bitowej). Poniższy kod zgłasza wyjątek:
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);
}
Wyjątek występuje, gdy maszyna JVM wykonuje kompilację bloku kodu i nie pojawia się z -Xint
flagą. Ponadto Arrays.fill(...)
instrukcja (jak wszystkie inne instrukcje w tym kodzie) jest konieczna, a wyjątek nie występuje, jeśli jej nie ma. Oczywiste jest, że ten możliwy błąd jest związany z pewną optymalizacją JVM. Jakieś pomysły na powód takiego zachowania?
Aktualizacja:
Widzę to zachowanie na 64-bitowej maszynie wirtualnej serwera HotSpot, wersji Java od 1.7.0_04 do 1.7.0_10 w Gentoo Linux, Debian Linux (obie wersje jądra 3.0) i MacOS Lion. Ten błąd można zawsze odtworzyć za pomocą powyższego kodu. Nie testowałem tego problemu z 32-bitowym JDK ani w systemie Windows. Wysłałem już raport o błędzie do Oracle (identyfikator błędu 7196857) i pojawi się on w publicznej bazie błędów Oracle za kilka dni.
Aktualizacja:
Oracle opublikowało ten błąd w swojej publicznej bazie danych błędów: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7196857