Adresse mémoire des objets en Java

1. Vue d'ensemble

Dans ce rapide tutoriel, nous allons voir comment trouver l'adresse mémoire des objets en Java.

Avant d'aller plus loin, il convient de mentionner que la disposition de la mémoire des zones de données d'exécution ne fait pas partie de la spécification JVM et est laissée à la discrétion de l'implémenteur. Par conséquent, chaque implémentation JVM peut avoir une stratégie différente pour mettre en page les objets et les tableaux en mémoire. Cela affectera à son tour les adresses mémoire.

Dans ce didacticiel, nous nous concentrons sur une implémentation JVM spécifique: la JVM HotSpot. Nous pouvons également utiliser les termes JVM et HotSpot JVM de manière interchangeable tout au long du didacticiel.

2. Dépendance

Pour trouver l'adresse mémoire des objets dans la JVM, nous allons utiliser l'outil Java Object Layout (JOL). Par conséquent, nous devons ajouter la dépendance jol-core :

 org.openjdk.jol jol-core 0.10 

3. Adresse mémoire

Pour trouver l'adresse mémoire d'un objet particulier dans la JVM, nous pouvons utiliser la méthode addressOf () :

String answer = "42"; System.out.println("The memory address is " + VM.current().addressOf(answer));

Cela imprimera:

The memory address is 31864981224

Il existe différents modes de référence compressés dans HotSpot JVM. En raison de ces modes, cette valeur peut ne pas être complètement précise. Par conséquent, nous ne devrions pas aller effectuer des manipulations de mémoire native basées sur cette adresse, car cela peut provoquer des corruptions de mémoire étranges.

De plus, les adresses mémoire dans la plupart des implémentations JVM sont sujettes à changement à mesure que le GC déplace les objets de temps en temps.

4. Code de hachage d'identité

Il y a une idée fausse courante selon laquelle les adresses mémoire des objets dans la JVM sont représentées dans le cadre de leurs implémentations toString par défaut , telles que [email protected] . Autrement dit, beaucoup pensent que le «60addb54» est l'adresse mémoire de cet objet particulier.

Vérifions cette hypothèse:

Object obj = new Object(); System.out.println("Memory address: " + VM.current().addressOf(obj)); System.out.println("toString: " + obj); System.out.println("hashCode: " + obj.hashCode()); System.out.println("hashCode: " + System.identityHashCode(obj));

Cela imprimera ce qui suit:

Memory address: 31879960584 toString: [email protected] hashCode: 1622006612 hashCode: 1622006612

Fait assez intéressant, le «60addb54» est la version hexadécimale du code de hachage, qui est 1622006612. La méthode hashCode () est l'une des méthodes courantes pour tous les objets Java. Lorsque nous ne déclarons pas de méthode hashCode () pour une classe, Java utilisera le code de hachage d'identité pour celle-ci.

Comme indiqué ci-dessus, le code de hachage d'identité (cette partie après @ dans toString ) et l'adresse mémoire sont différents .

5. Conclusion

Dans ce court tutoriel, nous avons vu comment trouver l'adresse mémoire des objets en Java.

Comme d'habitude, tous les exemples sont disponibles sur over sur GitHub.