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?
risposta
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.
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
@ user1110725, leggere attentamente. L'allineamento non è inteso solo per la garbage collection ma per l'accesso alla memoria in generale. – cyroxx
deve essere attivato +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.
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
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
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
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
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. –
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
- 1. Perché i frammenti IP devono essere multipli di 8 byte
- 2. Solo gli oggetti devono essere cancellati
- 3. Perché gli oggetti lanciati devono essere inizializzati in copia?
- 4. perché gli oggetti funzione devono essere pass-by-value
- 5. Gli oggetti di posta elettronica devono essere salvati in html?
- 6. Perché i bean Java devono essere serializzabili?
- 7. Gli oggetti NSString devono essere alloc e init?
- 8. Gli oggetti aziendali o le entità devono essere autovalegnati?
- 9. Gli oggetti entità devono essere esposti dal repository?
- 10. Perché gli oggetti di trasferimento devono implementare Serializable?
- 11. raggruppamento oggetti Java 8
- 12. Perché gli array statici non devono essere liberati?
- 13. ui-router Perché gli stati parentali devono essere astratti
- 14. In Java, perché equals() e hashCode() devono essere coerenti?
- 15. java @SafeVarargs perché i metodi privati devono essere definitivi
- 16. Gli ETAG HTTP devono essere case sensitive?
- 17. Gli elementi vettoriali devono essere mobili?
- 18. Perché i metodi parziali devono essere annullati?
- 19. Perché i tipi WinRT devono essere sigillati?
- 20. Perché gli oggetti in Redux dovrebbero essere immutabili?
- 21. Java 8 flusso - somma di oggetti
- 22. Perché non tutti gli argomenti della funzione devono essere dichiarati definitivi?
- 23. Quando devono essere scritti gli scenari di test BDD?
- 24. Gli oggetti enum dovrebbero essere apolidi?
- 25. Perché gli interpreti di lingua devono essere scritti nella lingua di destinazione?
- 26. Perché è necessario che le variabili devono essere inizializzate ai valori in Java
- 27. Gli oggetti del dominio e i JavaBeans semplici devono essere testati unitamente?
- 28. Come specificare che gli oggetti DateTime recuperati da EntityFramework devono essere DateTimeKind.UTC
- 29. Disegna diagramma a oggetti multipli in frammento
- 30. Unione di due elenchi di oggetti in java 8
Questo dipende da JVM. –
Mi dispiace non averlo notato ma stavo parlando di Hotspot JVM. – Nando
Quindi non lo sai _ lo sai - lo stai solo _read_ da qualche parte. –