In che modo la JVM assicurare che System.identityHashCode () non cambierà mai?
-
21-08-2019 - |
Domanda
Tipicamente l'implementazione predefinita di Object.hashCode()
è una funzione dell'indirizzo assegnato dell'oggetto in memoria (se questo non è obbligatorio per il JLS ). Dato che i derivatori VM oggetti Chi in memoria, perché il valore restituito da System.identityHashCode()
non cambiare durante la vita dell'oggetto?
Se si tratta di un calcolo "one-shot" (hashCode
dell'oggetto viene calcolato una volta e nascosto nell'intestazione oggetto o qualcosa del genere), allora vuol dire che è possibile che due oggetti hanno la stessa identityHashCode
( se capita di essere prima allocati allo stesso indirizzo in memoria)?
Soluzione
JVM moderni salvare il valore nell'intestazione oggetto. Credo che il valore è normalmente calcolato solo al primo utilizzo, al fine di mantenere il tempo trascorso in allocazione degli oggetti al minimo (a volte fino a partire da una dozzina di cicli). Il comune Sun JVM può essere compilato modo che il codice hash di identità è sempre 1 per tutti gli oggetti.
Più oggetti possono avere lo stesso codice identificativo hash. Questa è la natura di codici hash.
Altri suggerimenti
In risposta alla seconda domanda, a prescindere dalla realizzazione, è possibile che più oggetti abbiano lo stesso identityHashCode.
bug 6.321.873 per una breve discussione sul testo della javadoc, e un programma per dimostrare la non unicità.
L'intestazione di un oggetto in HotSpot è costituito da un puntatore alla classe e una parola "segno".
Il codice sorgente della struttura dati per la parola marchio può essere trovato il markOop.hpp
file . In questo file è un layout di memoria commento che descrive il marchio denominativo:
hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)
Qui possiamo vedere che il codice hash di identità per il normale oggetti Java su un sistema a 32 bit viene salvato nella parola contrassegno ed è lungo 25 bit.
L'orientamento generale per l'attuazione di una funzione di hashing è:
- lo stesso oggetto deve restituire un hashCode coerente , non dovrebbe cambiare con il tempo o dipendono informazioni variabili (ad esempio un algoritmo seminato da un numero o valori dei campi utente mutabile casuale
- la funzione di hash dovrebbe avere un buona distribuzione casuale , e con questo voglio dire, se si considera il codice hash come secchi, 2 oggetti devono mappare diversi secchi (codici hash) per quanto possibile. La possibilità che 2 oggetti avrebbe lo stesso codice hash dovrebbe essere raro - anche se possono accadere.
Per quanto ne so, questo è implementato per restituire il riferimento, che non cambierà mai nella vita degli oggetti.