Indirizzo di memoria degli oggetti in Java

1. Panoramica

In questo rapido tutorial, vedremo come trovare l'indirizzo di memoria degli oggetti in Java.

Prima di andare oltre, vale la pena ricordare che il layout di memoria delle aree dati di runtime non fa parte della specifica JVM ed è lasciato alla discrezione dell'implementatore. Pertanto, ciascuna implementazione JVM può avere una strategia diversa per il layout di oggetti e array in memoria. Ciò, a sua volta, influenzerà gli indirizzi di memoria.

In questo tutorial, ci concentriamo su un'implementazione JVM specifica: HotSpot JVM. Potremmo anche utilizzare i termini JVM e HotSpot JVM in modo intercambiabile durante il tutorial.

2. Dipendenza

Per trovare l'indirizzo di memoria degli oggetti nella JVM, utilizzeremo lo strumento Java Object Layout (JOL). Pertanto, dobbiamo aggiungere la dipendenza jol-core :

 org.openjdk.jol jol-core 0.10 

3. Indirizzo di memoria

Per trovare l'indirizzo di memoria di un particolare oggetto nella JVM, possiamo utilizzare il metodo addressOf () :

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

Questo stamperà:

The memory address is 31864981224

Esistono diverse modalità di riferimento compresso nella JVM HotSpot. A causa di queste modalità, questo valore potrebbe non essere completamente accurato. Pertanto, non dovremmo andare ed eseguire alcune manipolazioni della memoria nativa basate su questo indirizzo, poiché potrebbe causare strani corruzioni della memoria.

Inoltre, gli indirizzi di memoria nella maggior parte delle implementazioni JVM sono soggetti a modifiche quando il GC sposta gli oggetti di volta in volta.

4. Codice hash identità

C'è un malinteso comune che gli indirizzi di memoria degli oggetti nella JVM siano rappresentati come parte delle loro implementazioni predefinite di toString , come [email protected] . Cioè, molti pensano che "60addb54" sia l'indirizzo di memoria di quel particolare oggetto.

Controlliamo questa ipotesi:

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

Questo stamperà quanto segue:

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

In modo abbastanza interessante, "60addb54" è la versione esadecimale del codice hash, che è 1622006612. Il metodo hashCode () è uno dei metodi comuni per tutti gli oggetti Java. Quando non dichiariamo un metodo hashCode () per una classe, Java utilizzerà il codice hash dell'identità per esso.

Come mostrato sopra, il codice hash identità (quella parte dopo @ in toString ) e l'indirizzo di memoria sono diversi .

5. conclusione

In questo breve tutorial, abbiamo visto come trovare l'indirizzo di memoria degli oggetti in Java.

Come al solito, tutti gli esempi sono disponibili su GitHub.