Según el JLS, una int
matriz debe rellenarse con ceros justo después de la inicialización. Sin embargo, me enfrento a una situación en la que no es así. Tal comportamiento ocurre primero en JDK 7u4 y también ocurre en todas las actualizaciones posteriores (uso la implementación de 64 bits). El siguiente código arroja una excepción:
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);
}
La excepción ocurre después de que la JVM realiza la compilación del bloque de código y no surge con el -Xint
indicador. Además, la Arrays.fill(...)
declaración (como todas las demás declaraciones en este código) es necesaria, y la excepción no ocurre si está ausente. Está claro que este posible error está limitado con alguna optimización de JVM. ¿Alguna idea por la razón de tal comportamiento?
Actualización:
veo este comportamiento en la máquina virtual del servidor HotSpot de 64 bits, la versión Java de 1.7.0_04 a 1.7.0_10 en Gentoo Linux, Debian Linux (versión del kernel 3.0) y MacOS Lion. Este error siempre se puede reproducir con el código anterior. No probé este problema con un JDK de 32 bits o en Windows. Ya envié un informe de error a Oracle (ID de error 7196857) y aparecerá en la base de datos pública de errores de Oracle en unos días.
Actualización:
Oracle publicó este error en su base de datos pública de errores: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7196857
Respuestas:
Aquí nos enfrentamos a un error en el compilador JIT. El compilador determina que la matriz asignada se llena después de la asignación
Arrays.fill(...)
, pero la verificación de usos entre la asignación y el llenado es defectuosa. Entonces, el compilador realiza una optimización ilegal: omite la puesta a cero de la matriz asignada.Este error se coloca en el rastreador de errores de Oracle ( ID de error 7196857 ). Desafortunadamente, no esperé ninguna aclaración de Oracle sobre los siguientes puntos. Como veo, este error es específico del sistema operativo: es absolutamente reproducible en Linux y Mac de 64 bits, pero, como veo por los comentarios, no se reproduce regularmente en Windows (para versiones similares de JDK). Además, sería bueno saber cuándo se solucionará este error.
Por el momento solo hay consejos: no use JDK1.7.0_04 o posterior si depende de JLS para las matrices recientemente declaradas.
Actualización al 5 de octubre:
En el nuevo Build 10 del JDK 7u10 (acceso anticipado) lanzado el 4 de octubre de 2012, este error se corrigió al menos para el sistema operativo Linux (no probé para otro). Gracias a @Makoto, quien descubrió que este error ya no está disponible para el acceso público en la base de datos de errores de Oracle. Desafortunadamente, no sé por las razones por las que Oracle lo eliminó del acceso público, pero está disponible en el caché de Google . Además, este error ha llamado la atención de RedHat: los identificadores CVE CVE-2012 a 4.420 ( Bugzilla ) y CVE-2012-4416 ( Bugzilla ) fueron asignados a esta falla.
fuente
Hice algún cambio en tu código. No es un problema de desbordamiento de enteros. Ver el código, arroja una excepción en tiempo de ejecución
fuente