Matriz Java: int inicializa com elementos diferentes de zero

De acordo com o JLS, um array int deve ser preenchido por zeros logo após a boot. No entanto, estou diante de uma situação em que não é. Esse comportamento ocorre primeiro no JDK 7u4 e também ocorre em todas as atualizações posteriores (eu uso a implementação de 64 bits). O código a seguir lança exceção:

 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); } 

A exceção ocorre depois que a JVM executa a compilation do bloco de códigos e não surge com o sinalizador -Xint . Além disso, a Arrays.fill(...) (como todas as outras instruções neste código) é necessária e a exceção não ocorre se estiver ausente. É claro que esse possível bug é limitado com alguma otimização da JVM. Alguma idéia para a razão de tal comportamento?

Atualizar:
Eu vejo esse comportamento na VM do servidor HotSpot de 64 bits, versão Java de 1.7.0_04 a 1.7.0_10 no Gentoo Linux, Debian Linux (versão kernel 3.0) e MacOS Lion. Este erro sempre pode ser reproduzido com o código acima. Eu não testei esse problema com um JDK de 32 bits ou no Windows. Eu já enviei um relatório de bug para o Oracle (bug id 7196857) e ele aparecerá no database de bugs públicos da Oracle em poucos dias.

Atualizar:
A Oracle publicou este bug em seu database público de bugs: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7196857

Aqui nos deparamos com um bug no compilador JIT. O compilador determina que a matriz alocada é preenchida após a alocação em Arrays.fill(...) , mas a verificação de usos entre a alocação e o preenchimento está com falha. Assim, o compilador executa uma otimização ilegal – ele pula o zero da matriz alocada.

Esse bug é colocado no bug tracker do Oracle ( bug id 7196857 ). Infelizmente, não esperei por nenhum esclarecimento da Oracle sobre os seguintes pontos. Como eu vejo, esse bug é específico do sistema operacional: é absolutamente reproduzível no Linux e Mac de 64 bits, mas, como vejo nos comentários, ele não é reproduzido regularmente no Windows (para versões similares do JDK). Além disso, seria bom saber quando esse bug será corrigido.

Há apenas conselhos no momento: não use o JDK1.7.0_04 ou posterior se você depender do JLS para matrizes recém-declaradas.

Atualização em 5 de outubro:

No novo Build 10 do JDK 7u10 (access antecipado) lançado em 04 de outubro de 2012, este bug foi corrigido pelo menos para o Linux OS (eu não testei para outros). Obrigado ao @Makoto, que descobriu que este bug não está mais disponível para access público no database de bugs da Oracle. Infelizmente, eu não sei por razões que a Oracle removeu do access público, mas está disponível no cache do Google. Além disso, esse bug chamou a atenção do Redhat: os identificadores CVE CVE-2012-4420 ( bugzilla ) e CVE-2012-4416 ( bugzilla ) foram atribuídos a essa falha.

Eu fiz algumas alterações no seu código. Não é um problema de estouro de inteiro. Veja o código, ele lança uma exceção em tempo de execução

  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)); } } for (int ii = 0, len = a.length; ii < len; ii++) a[ii] = 0; for (int j = 0; j < a.length; ++j) a[j] = Integer.MAX_VALUE - 1; for (int j = 0; j < a.length; ++j) n++; }