2012-08-12 15 views
14

So che Java usa il padding; gli oggetti devono essere multipli di 8 byte. Tuttavia, non vedo lo scopo di esso. A cosa serve? Qual è esattamente il suo scopo principale?Perché gli oggetti Java devono essere multipli di 8?

+6

Questo dipende da JVM. –

+0

Mi dispiace non averlo notato ma stavo parlando di Hotspot JVM. – Nando

+3

Quindi non lo sai _ lo sai - lo stai solo _read_ da qualche parte. –

risposta

16

Il suo scopo è alignment, che consente un accesso più veloce alla memoria a costo di un po 'di spazio. Se i dati non sono allineati, il processore deve eseguire alcuni spostamenti per accedervi dopo aver caricato la memoria.

Inoltre, la raccolta dei dati inutili è semplificata (e velocizzata), maggiore è la dimensione dell'unità di allocazione più piccola.

È improbabile che Java abbia un requisito di 8 byte (ad eccezione dei sistemi a 64 bit), ma dal momento che le architetture a 32 bit erano la norma quando veniva creato Java è possibile che l'allineamento a 4 byte sia richiesto nello standard Java.

+0

Ho trovato queste informazioni su [Wikipedia] (http://en.wikipedia.org/wiki/Java_performance#Memory_usage) e [Javamex] (http://www.javamex.com/tutorials/memory/object_memory_usage.shtml) dicendo che è 8 byte. Ma l'unico scopo è la garbage collection? – Nando

+1

@ user1110725, leggere attentamente. L'allineamento non è inteso solo per la garbage collection ma per l'accesso alla memoria in generale. – cyroxx

+0

deve essere attivato +1 –

-1

Le dimensioni dei tipi di dati in Java sono multipli di 8 bit (non byte) perché le dimensioni delle parole nella maggior parte dei processori moderni sono multipli di 8 bit: 16 bit, 32 bit, 64 bit. In questo modo, un campo in un oggetto può essere adattato ("allineato") in una parola o in una parola e sprecare il minimo spazio possibile, sfruttando le istruzioni del processore sottostante per operare su dati in formato word.

+5

No, byte. La maggior parte (tutti?) Di JVM allinea i propri dati ad almeno 4 limiti di byte, ad eccezione dei piccoli primitivi negli array. – U2EF1

+0

Non sto parlando di tipi di dati, ma di oggetti. Con ciò intendo, i miei oggetti. Sono sempre un multiplo di 8 byte. Almeno, questo è quello che leggo. Ho trovato queste informazioni su [Wikipedia] (http://en.wikipedia.org/wiki/Java_performance#Memory_usage) e [Javamex] (http://www.javamex.com/tutorials/memory/object_memory_usage.shtml). – Nando

4

La risposta accettata è la speculazione (ma parzialmente corretta). Ecco la vera risposta.

Primo, per il credito di @U2EF1, uno dei vantaggi dei limiti di 8 byte è che 8 byte sono l'accesso ottimale alla maggior parte dei processori. Tuttavia, c'era ancora di più nella decisione.

Se si dispone di riferimenti a 32 bit, è possibile indirizzare fino a 2^32 o 4 GB di memoria (praticamente si ottiene meno, anche più di 3,5 GB). Se si hanno riferimenti a 64 bit, è possibile indirizzare 2^64, che è terrabyte di memoria. Tuttavia, con riferimenti a 64 bit, tutto tende a rallentare e richiedere più spazio. Ciò è dovuto al sovraccarico dei processori a 32 bit che si occupano di 64-bit, e su tutti i processori più cicli GC a causa di meno spazio e più garbage collection.

Quindi, i creatori hanno preso una via di mezzo e hanno deciso i riferimenti a 35 bit, che consentono fino a 2^35 o 32 GB di memoria e occupano meno spazio in modo da avere gli stessi vantaggi delle prestazioni dei riferimenti a 32 bit. Questo viene fatto prendendo un riferimento a 32 bit e spostandolo lasciato 3 bit durante la lettura e spostandolo a destra di 3 bit quando si memorizzano i riferimenti. Ciò significa che tutti gli oggetti devono essere allineati sui confini 2^3 (8 byte). Questi sono chiamati puntatori oggetto ordinario compresso o opsop compresso.

Perché non riferimenti a 36 bit per l'accesso a 64 GB di memoria? Bene, è stato un compromesso. Avresti bisogno di molto spazio sprecato per gli allineamenti a 16-byte e, per quanto ne so, la maggior parte dei processori non riceve alcun beneficio in termini di velocità dagli allineamenti a 16-byte rispetto agli allineamenti a 8-byte.

Si noti che la JVM non si preoccupa di utilizzare oops compressi a meno che la memoria massima sia impostata su un valore superiore a 4 GB, che non è predefinita. Puoi effettivamente abilitarli con il flag -XX:+UsedCompressedOops.

Questo era il giorno delle macchine virtuali a 32 bit per fornire la memoria extra disponibile sui sistemi a 64 bit. Per quanto ne so, non vi è alcuna limitazione con macchine virtuali a 64 bit.

Origine: Prestazioni Java: la Guida definitiva, Capitolo 8

+1

La decisione per l'allineamento a 8 byte è molto più vecchia della funzione compresso oops e si applica anche alle JVM a 32 bit, che non supportano più di 2 GB. La tua ipotesi secondo cui "* le future JVM supporteranno riferimenti a 64 bit *" non ha senso, poiché tutte le JVM a 64 bit * fanno * supportano riferimenti a 64 bit. Vengono utilizzati quando l'heap è più grande di 32 GB o quando si specifica '-XX: -UsedCompressedOops' o quando si utilizza una JVM precedente, che non ha la funzione oops compressa. – Holger

+0

Forse formulato male, ma intendevo riferimenti che usano _all_ 64-bit, non che non ci fossero "riferimenti memorizzati in valori a 64 bit". L'ultima volta che ho controllato (che era un po 'di tempo fa), non si poteva usare un heap di memoria 2^64 in una JVM. –

+0

Sarei molto sorpreso, se dovessi trovare un sistema reale (hardware + sistema operativo) che supporti l'allocazione di 2⁶⁴ byte. Mi chiedo, se capisci, quanto sia grande. Tuttavia, è possibile utilizzare un heap grande quanto il sistema sottostante lo supporta. Se pensi che hai incontrato una JVM a 64 bit che supporta meno del sistema operativo, devi essere più specifico. – Holger

Problemi correlati