Selon le JLS, un int
tableau doit être rempli de zéros juste après l'initialisation. Cependant, je suis confronté à une situation où ce n'est pas le cas. Un tel comportement se produit en premier dans JDK 7u4 et se produit également dans toutes les mises à jour ultérieures (j'utilise une implémentation 64 bits). Le code suivant lève une 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);
}
L'exception se produit après que la JVM a effectué la compilation du bloc de code et ne se produit pas avec l' -Xint
indicateur. En outre, l' Arrays.fill(...)
instruction (comme toutes les autres instructions de ce code) est nécessaire et l'exception ne se produit pas si elle est absente. Il est clair que ce bogue éventuel est lié à une certaine optimisation JVM. Des idées pour la raison d'un tel comportement?
Mise à jour:
Je vois ce comportement sur la VM serveur HotSpot 64 bits, la version Java de 1.7.0_04 à 1.7.0_10 sur Gentoo Linux, Debian Linux (les deux versions du noyau 3.0) et MacOS Lion. Cette erreur peut toujours être reproduite avec le code ci-dessus. Je n'ai pas testé ce problème avec un JDK 32 bits ou sous Windows. J'ai déjà envoyé un rapport de bogue à Oracle (id de bogue 7196857) et il apparaîtra dans la base de données publique de bogues d'Oracle dans quelques jours.
Mise à jour:
Oracle a publié ce bogue dans sa base de données publique de bogues: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7196857
Réponses:
Ici, nous sommes confrontés à un bogue dans le compilateur JIT. Le compilateur détermine que le tableau alloué est rempli après l'allocation
Arrays.fill(...)
, mais la vérification des utilisations entre l'allocation et le remplissage est erronée. Ainsi, le compilateur effectue une optimisation illégale - il ignore la remise à zéro du tableau alloué.Ce bogue est placé dans Oracle Bug Tracker ( id de bogue 7196857 ). Malheureusement, je n'ai pas attendu d'éclaircissements d'Oracle sur les points suivants. Comme je le vois, ce bogue est spécifique au système d'exploitation: il est absolument reproductible sur Linux et Mac 64 bits, mais, comme je le vois dans les commentaires, il ne se reproduit pas régulièrement sous Windows (pour des versions similaires de JDK). De plus, il serait bon de savoir quand ce bug sera corrigé.
Il n'y a qu'un conseil pour le moment: n'utilisez pas JDK1.7.0_04 ou version ultérieure si vous dépendez de JLS pour les tableaux nouvellement déclarés.
Mise à jour le 5 octobre:
Dans la nouvelle Build 10 du JDK 7u10 (accès anticipé) sortie le 04 octobre 2012, ce bogue a été corrigé au moins pour Linux OS (je n'ai pas testé d'autres). Merci à @Makoto, qui a constaté que ce bogue n'est plus disponible pour un accès public dans la base de données de bogues Oracle. Malheureusement, je ne sais pas pour les raisons pour lesquelles Oracle l'a retiré de l'accès public, mais il est disponible dans le cache de Google . Aussi, ce bug a retenu l'attention de Redhat: les identifiants CVE CVE-2012-4420 ( bugzilla ) et CVE-2012-4416 ( bugzilla ) ont été affectés à cette faille.
la source
J'ai fait quelques changements dans votre code. Ce n'est pas un problème de débordement d'entier. Voir le code, il lève une exception lors de l'exécution
la source