Java: la variabile nulla richiede spazio nella memoria

class CheckStore { private String displayText; private boolean state; private String meaningfulText; private URL url; public CheckStore(String text, boolean state) { this.displayText = text; this.state = state; } : : } 

Poiché sto inizializzando solo due variabili ( displayText e state ) nel costruttore, Will il resto di due variabili ( meaningfulText e url che avranno il valore null ) richiederà spazio nella memoria per memorizzare il valore null .

Q1. Penso che richiederanno spazio. Se lo faranno, quanta memoria ha un valore null in memoria (come int richiede 4 byte).

Q2. Quanto spazio occupa una stringa nella memoria. Credo che dipenderà dalla lunghezza della stringa. Quindi quanto spazio occupa una stringa di quanta lunghezza?

In Java, null è solo un valore che può avere un riferimento (che in pratica è un puntatore limitato). Significa che il riferimento si riferisce a nulla. In questo caso continui a consumare lo spazio per il riferimento. Questo è 4 byte su sistemi a 32 bit o 8 byte su sistemi a 64 bit. Tuttavia, non stai consumando spazio per la class a cui fa riferimento il riferimento fino a quando non assegni effettivamente un’istanza di quella class a cui indirizzare il riferimento.

Modifica: per quanto riguarda la stringa, una String in Java richiede 16 bit (2 byte) per ciascun carattere, oltre a una piccola quantità di overhead di contabilità, che è probabilmente non documentato e specifico per l’implementazione.

Vorrei aggiungere:

  1. la variabile del tipo di riferimento verrà inizializzata come valore nullo.
  2. null non è un object. perché (null instanceof Object) è uguale a false
  3. c’è solo un valore nullo in JVM. Non importa quante variabili si riferiscono a null.

    Object s = (String) null;

    Object i = (Integer) null;

    System.out.println (s == i); // true

Puoi usare jol per ottenere il layout di quella class. (Tuttavia, fai attenzione, potresti avere bisogno di una comprensione più approfondita dei meccanismi che stanno dietro, non fidarti ciecamente del risultato ed essere consapevole che è solo una stima per la VM attualmente utilizzata (1.7.0_76 x64 win nel mio caso :):

Io uso la versione CLI immagino che il metodo corretto sarebbe quello di includere la libreria nel progetto, ma comunque, sembra funzionare in questo modo:

 test>java -cp target\classs;jol-cli-0.3.1-full.jar org.openjdk.jol.Main internals test.CheckStore Running 64-bit HotSpot VM. Using compressed oop with 0-bit shift. Using compressed klass with 0-bit shift. Objects are 8 bytes aligned. Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] VM fails to invoke the default constructor, falling back to class-only introspection. test.CheckStore object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 12 (object header) N/A 12 1 boolean CheckStore.state N/A 13 3 (alignment/padding gap) N/A 16 4 String CheckStore.displayText N/A 20 4 String CheckStore.meaningfulText N/A 24 4 URL CheckStore.url N/A 28 4 (loss due to the next object alignment) Instance size: 32 bytes (estimated, the sample instance is not available) Space losses: 3 bytes internal + 4 bytes external = 7 bytes total 

e lo stesso con oops automatici compressi distriggersti:

 test>java -XX:-UseCompressedOops -cp target\classs;jol-cli-0.3.1-full.jar org.openjdk.jol.Main internals test.CheckStore Running 64-bit HotSpot VM. Objects are 8 bytes aligned. Field sizes by type: 8, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] Array element sizes: 8, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] VM fails to invoke the default constructor, falling back to class-only introspection. test.CheckStore object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 16 (object header) N/A 16 1 boolean CheckStore.state N/A 17 7 (alignment/padding gap) N/A 24 8 String CheckStore.displayText N/A 32 8 String CheckStore.meaningfulText N/A 40 8 URL CheckStore.url N/A Instance size: 48 bytes (estimated, the sample instance is not available) Space losses: 7 bytes internal + 0 bytes external = 7 bytes total 

Questi sono solo i layout per l’object stesso se i tuoi campi sono nulli, quindi non puntano a più oggetti, altrimenti devi guardare anche i tipi di destinazione ( URL e String ). (E se hai più istanze di tutte, dipende se usi più volte o più volte). Un campo null non può essere saltato in memoria, poiché richiederebbe il ridimensionamento dell’istanza al momento dell’assegnazione. Quindi i campi sono tutti pre-costruiti, semplicemente non fanno riferimento agli oggetti allocati da qualche altra parte sull’heap.

NB: si ottengono ulteriori dettagli se si implementa un costruttore predefinito, ma il dimensionamento in questo caso specifico sarebbe lo stesso. Se ti chiedi da dove provenga la sequenza e il padding dei campi, puoi controllare questo articolo – (fondamentalmente allinea gli oggetti su 8 byte, ordina i campi per dimensione, raggruppa lo stesso tipo insieme, i riferimenti durano. Allineato a 4 byte.)

Null significa 0. Di solito c’è un punto null definito in memoria. Ogni volta che uno lo punta usando un linguaggio di programmazione. Tutto punta allo stesso posto. Significa che viene consumata solo una memoria da 4 byte per NULL. Quindi qualunque cosa accada non consuma più memoria. La definizione di NULL è specifica del linguaggio ma la definisce void * ptr = 0; è comune in C e C ++. JAVA deve averlo definito allo stesso modo. Non è ansible indicare niente ofc. Devi indicare qualcosa. Ma definiamo un nulla comune e tutto indica che esso consuma solo quello spazio.