Speicheradresse von Objekten in Java

1. Übersicht

In diesem kurzen Tutorial erfahren Sie, wie Sie die Speicheradresse von Objekten in Java ermitteln.

Bevor wir fortfahren, ist zu erwähnen, dass das Speicherlayout von Laufzeitdatenbereichen nicht Teil der JVM-Spezifikation ist und im Ermessen des Implementierers liegt. Daher kann jede JVM-Implementierung eine andere Strategie zum Layouten von Objekten und Arrays im Speicher haben. Dies wirkt sich wiederum auf die Speicheradressen aus.

In diesem Tutorial konzentrieren wir uns auf eine bestimmte JVM-Implementierung: die HotSpot-JVM. Wir können auch die JVM- und HotSpot-JVM-Begriffe im gesamten Lernprogramm austauschbar verwenden.

2. Abhängigkeit

Um die Speicheradresse von Objekten in der JVM zu ermitteln, verwenden wir das Java Object Layout (JOL) -Tool. Daher müssen wir die Jol-Core- Abhängigkeit hinzufügen :

 org.openjdk.jol jol-core 0.10 

3. Speicheradresse

Um die Speicheradresse eines bestimmten Objekts in der JVM zu ermitteln, können Sie die addressOf () -Methode verwenden:

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

Dies wird gedruckt:

The memory address is 31864981224

In der HotSpot JVM gibt es verschiedene komprimierte Referenzmodi. Aufgrund dieser Modi ist dieser Wert möglicherweise nicht vollständig genau. Daher sollten wir einige native Speichermanipulationen basierend auf dieser Adresse nicht durchführen, da dies zu seltsamen Speicherbeschädigungen führen kann.

Außerdem können sich die Speicheradressen in den meisten JVM-Implementierungen ändern, wenn der GC die Objekte von Zeit zu Zeit bewegt.

4. Identity Hash Code

Es gibt ein weit verbreitetes Missverständnis, dass die Speicheradressen von Objekten in der JVM als Teil ihrer Standard- to-String- Implementierungen dargestellt werden, z. B. [E-Mail-geschützt] . Das heißt, viele denken, dass "60addb54" die Speicheradresse dieses bestimmten Objekts ist.

Überprüfen wir diese Annahme:

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));

Dadurch wird Folgendes gedruckt:

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

Interessanterweise ist „60addb54“ die hexadezimale Version des Hash-Codes 1622006612. Die Methode hashCode () ist eine der gemeinsamen Methoden für alle Java-Objekte. Wenn wir keine hashCode () -Methode für eine Klasse deklarieren , verwendet Java den Identitäts-Hashcode dafür.

Wie oben gezeigt, unterscheiden sich der Identitäts-Hash-Code (der Teil nach @ in toString ) und die Speicheradresse .

5. Schlussfolgerung

In diesem kurzen Tutorial haben wir gesehen, wie die Speicheradresse von Objekten in Java ermittelt wird.

Wie üblich sind alle Beispiele auf GitHub verfügbar.