70 votes

Est-ce une JVM bug ou "comportement attendu"?

J'ai remarqué un comportement inattendu (inattendue par rapport à mes attentes personnelles), et je me demandais si quelque chose si il y a un bug dans la JVM ou si c'est peut-être une frange cas où je ne comprends pas certains détails exactement ce qui est censé se produire. Supposons que nous ayons le code suivant dans la méthode main par lui-même:

int i;
int count = 0;
for(i=0; i < Integer.MAX_VALUE; i+=2){
  count++;
}
System.out.println(i++);

Le naïf espoir serait que ce serait d'imprimer Integer.MAX_VALUE-1, le plus grand même représentable int. Cependant, je crois que l'arithmétique des nombres entiers est censé "rollover" en Java, donc, l'ajout de 1 Integer.MAX_VALUE devrait entraîner Integer.MIN_VALUE. Depuis Integer.MIN_VALUE est encore moins Integer.MAX_VALUE, la boucle se garder d'une itération dans le négatif, même ints. Finalement, il serait revenir à 0, et ce processus doit se répéter comme une boucle infinie.

Lorsque j'ai fait d'exécuter ce code, j'obtiens non-déterministe résultats. Le résultat est imprimé tend à être de l'ordre de un demi-million de dollars, mais la valeur exacte varie. N'est donc pas seulement la boucle s'arrêter quand je pense qu'elle doit être une boucle infinie, mais il semble pour mettre fin au hasard. Ce qui se passe?

Ma conjecture est que c'est soit un bug dans la JVM, ou il y a beaucoup de funky optimisation en cours qui ont fait de ce comportement attendu. Qui est-il?

48voto

Kevin Bourrillion Points 19677

Bug connu. Liées à la

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6196102

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6357214

et pour les autres.

Je pense qu'ils sont considérés comme à faible priorité à corriger car ils n'entrent pas dans le monde réel.

15voto

Jon Skeet Points 692016

Ce qui est bizarre. Il ressemble certainement un bug quelque part. J'obtiens les mêmes résultats à chaque fois avec le même code, mais des modifications insignifiantes pour le code à modifier le résultat. Par exemple:

public class Test {
  public static void main(String[] args) {
    int i;
    int count = 0;
    for (i = 0; i < Integer.MAX_VALUE; i+=2) {
      count++;
    }
    System.out.println(i);
    System.out.println(i < Integer.MAX_VALUE);
  }
}

... toujours des impressions 2147483640 et vrai

considérant que la présente:

public class Test {
  public static void main(String[] args) {
    int i;
    for (i = 0; i < Integer.MAX_VALUE; i+=2) {
    }
    System.out.println(i);
    System.out.println(i < Integer.MAX_VALUE);
  }
}

toujours des impressions de -2147483648 et vrai.

Très, très bizarre.

(C'est l'exécution d'une OpenJDK 1.6 VM sous Linux.)

EDIT: l'Exécution de OpenJDK 1.7 sur Windows 7, je ne vois pas le problème:

java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b78)
Java HotSpot(TM) Client VM (build 17.0-b05, mixed mode, sharing)

4voto

Matthew Willis Points 26453

Essayez d'ajouter de l' System.out.println(count);

Je me demande si il y a d'optimisation du produit, étant donné que le comte n'est jamais lire.

Modifier - une autre réponse a donné le lien de bogues dans l'Oracle du bug tracker. Dessin:

  • 6196102 mentionne notamment qu'il y a une mise en forme canonique d'un bug où les Integer.MAX_VALUE .
  • Java doit être en essayant d'optimiser la boucle, car count n'est jamais lire.

Toutefois, il est peu probable de se produire dans la pratique, parce que:

  • Integer.MAX_VALUE est peu probable que la boucle de la garde
  • Habituellement, les boucles de faire un travail qui n'a pas permis à cette optimisation, en premier lieu,

2voto

Kris Points 8813

Cela semble être une boucle optimisations que j'observe le même résultat, mais SI j'ai aussi imprimer count alors que le résultat des modifications.

I. e.

    int i;
    int count = 0;
    for(i=0; i < Integer.MAX_VALUE; i+=2){
      count++;
    }
    System.out.println(count);
    System.out.println(i++);

Produit 2147483638 alors que le code original produit 457158 (ou similaire)

0voto

Jigar Joshi Points 116533
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Java HotSpot(TM) Client VM (build 17.1-b03, mixed mode, sharing)

fonctionne comme prévu. boucle infinie

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X