De acordo com o JLS, uma int
matriz deve ser preenchida por zeros logo após a inicialização. No entanto, estou diante de uma situação em que não é. Esse comportamento ocorre primeiro no JDK 7u4 e também em todas as atualizações posteriores (eu uso a implementação de 64 bits). O código a seguir gera uma 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 após a JVM executar a compilação do bloco de código e não surge com o -Xint
sinalizador. Além disso, a Arrays.fill(...)
instrução (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 está associado a alguma otimização da JVM. Alguma idéia para a razão de tal comportamento?
Atualização:
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 do kernel 3.0) e MacOS Lion. Este erro sempre pode ser reproduzido com o código acima. Não testei esse problema com um JDK de 32 bits ou no Windows. Já enviei um relatório de bug para o Oracle (id 7196857) e ele aparecerá no banco de dados público de bug do Oracle em alguns dias.
Atualização: a
Oracle publicou esse bug em seu banco de dados público: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7196857
Respostas:
Aqui nos deparamos com um bug no compilador JIT. O compilador determina que a matriz alocada é preenchida após a alocação
Arrays.fill(...)
, mas a verificação de usos entre a alocação e o preenchimento está com defeito. Portanto, o compilador executa uma otimização ilegal - ignora o zeramento da matriz alocada.Este bug é colocado no rastreador de erros do Oracle ( id 7196857 ). Infelizmente, não esperei nenhum esclarecimento da Oracle sobre os seguintes pontos. A meu ver, 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 semelhantes do JDK). Além disso, seria bom saber quando esse bug será corrigido.
No momento, existem apenas conselhos: não use o JDK1.7.0_04 ou posterior se você depende do JLS para matrizes recém-declaradas.
Atualização em 5 de outubro:
No novo Build 10 do JDK 7u10 (acesso antecipado) lançado em 04 de outubro de 2012, esse bug foi corrigido pelo menos para o Linux OS (não testei para outros). Obrigado a @Makoto, que descobriu que esse bug não está mais disponível para acesso público no banco de dados de erros do Oracle. Infelizmente, não sei pelos motivos que a Oracle o removeu do acesso público, mas está disponível no cache do Google . Além disso, esse bug chamou a atenção do Redhat: os identificadores do CVE CVE-2012-4420 ( bugzilla ) e CVE-2012-4416 ( bugzilla ) foram atribuídos a essa falha.
fonte
Fiz algumas alterações no seu código. Não é um problema de excesso de número inteiro. Veja o código, ele lança uma exceção em tempo de execução
fonte