Comment la JVM garantit-elle que System.identityHashCode () ne changera jamais?

En général, l’implémentation par défaut de Object.hashCode() est une fonction de l’adresse allouée de l’object en mémoire (bien que cela ne soit pas obligatoire pour JLS ). Étant donné que la machine virtuelle dérive les objects en mémoire, pourquoi la valeur renvoyée par System.identityHashCode() ne change-t-elle jamais pendant la durée de vie de l’object?

S’il s’agit d’un calcul “one-shot” (le hashCode l’object est calculé une fois et stocké dans l’en-tête de l’object), cela signifie-t-il qu’il est possible que deux objects aient le même identityHashCode (s’ils sont alloués en premier) à la même adresse en mémoire)?

Les machines virtuelles Java modernes enregistrent la valeur dans l’en-tête de l’object. Je pense que la valeur est généralement calculée uniquement lors de la première utilisation afin de réduire au minimum le temps consacré à l’atsortingbution des objects (parfois jusqu’à une douzaine de cycles). La JVM commune de Sun peut être compilée pour que le code de hachage d’identité soit toujours égal à 1 pour tous les objects.

Plusieurs objects peuvent avoir le même code de hachage d’identité. C’est la nature des codes de hachage.

En réponse à la deuxième question, quelle que soit l’implémentation, plusieurs objects peuvent avoir le même identityHashCode.

Voir le bogue 6321873 pour une brève discussion sur le libellé du javadoc et un programme pour démontrer l’absence d’unicité.

L’en-tête d’un object dans HotSpot se compose d’un pointeur de classe et d’un mot “mark”.

Le code source de la structure de données du mot- markOop.hpp se trouve dans le fichier markOop.hpp . Dans ce fichier, il y a un commentaire décrivant la disposition de la mémoire du mot-clé:

hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)

Ici, nous pouvons voir que le code de hachage d’identité pour les objects Java normaux sur un système 32 bits est enregistré dans le mot de marque et qu’il est long de 25 bits.

La règle générale pour l’implémentation d’une fonction de hachage est la suivante:

  • le même object doit renvoyer un hashCode cohérent , il ne doit pas changer avec le temps ou dépendre d’une information de variable (par exemple, un algorithme associé à un nombre aléatoire ou à des valeurs de champs de membre mutables)
  • la fonction de hachage devrait avoir une bonne dissortingbution aléatoire , ce qui signifie que si vous considérez le code de hachage comme des compartiments, 2 objects doivent être mappés autant que possible sur différents compartiments (codes de hachage). La possibilité que 2 objects aient le même code de hachage devrait être rare – même si cela peut arriver.

Pour autant que je sache, cela est implémenté pour renvoyer la référence, qui ne changera jamais dans la durée de vie d’un object.