Dove viene memorizzata la lunghezza dell'array in JVM?

1. Panoramica

In questo breve tutorial, vedremo come e dove la JVM HotSpot memorizza la lunghezza dell'array.

Di solito, 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.

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

2. Dipendenza

Per ispezionare il layout di memoria degli array nella JVM, utilizzeremo lo strumento JOL (Java Object Layout). Pertanto, dobbiamo aggiungere la dipendenza jol-core :

 org.openjdk.jol jol-core 0.10 

3. Lunghezza array

La JVM HotSpot utilizza una struttura dati denominata Ordinary Object Pointers (OOP) per rappresentare i puntatori agli oggetti. Per essere più precisi, l'HotSpot JVM rappresenta gli array con uno speciale OOP chiamato arrayOop . Ogni arrayOop include un'intestazione di oggetto con i seguenti dettagli:

  • Una parola di contrassegno per memorizzare il codice hash identità o le informazioni GC
  • Una parola di classe per memorizzare i metadati generali della classe
  • 4 byte che rappresentano la lunghezza dell'array

Pertanto, la JVM memorizza la lunghezza dell'array nell'intestazione dell'oggetto .

Verifichiamo questo controllando il layout di memoria di un array:

int[] ints = new int[42]; System.out.println(ClassLayout.parseInstance(ints).toPrintable());

Come mostrato sopra, stiamo analizzando il layout di memoria da un'istanza di array esistente. Ecco come la JVM definisce l' int [] :

[I object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1) # mark 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) # mark 8 4 (object header) 6d 01 00 f8 (01101101 00000001 00000000 11111000) (-134217363) #klass 12 4 (object header) 2a 00 00 00 (00101010 00000000 00000000 00000000) (42) # array length 16 168 int [I. N/A Instance size: 184 bytes

Come accennato in precedenza, la JVM memorizza la lunghezza dell'array all'interno dell'intestazione dell'oggetto dopo le parole mark e klass. Inoltre, la lunghezza dell'array verrà archiviata in 4 byte, quindi non può essere maggiore del valore massimo per un numero intero a 32 bit.

Dopo l'intestazione dell'oggetto, la JVM memorizza gli elementi dell'array effettivi. Poiché abbiamo un array di 42 numeri interi, la dimensione totale dell'array è 168 byte - 42 moltiplicato per 4.

4. Conclusione

In questo breve tutorial, abbiamo visto come la JVM memorizza la lunghezza dell'array.

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