Domyślna implementacja hashCode()
na HotSpot zwraca wartość random value i zapisuje ją w nagłówku obiektu. To wydaje się nie zmieniły w Java 8 gdzie wartość hash oblicza się poprzez wywołanie os::random()
:Dlaczego funkcja Object.hashCode() zwraca tę samą wartość w różnych przebiegach
static inline intptr_t get_next_hash(Thread * Self, oop obj) {
intptr_t value = 0 ;
if (hashCode == 0) {
// This form uses an unguarded global Park-Miller RNG,
// so it's possible for two threads to race and generate the same RNG.
// On MP system we'll have lots of RW access to a global, so the
// mechanism induces lots of coherency traffic.
value = os::random() ;
} else
...
Zastanawiam się dlaczego hashCode()
stale zwraca taką samą wartość, również po wyłączeniu JVM które próbowałem poprzez wykonanie prostego testu poniżej, ponowne uruchomienie komputera i ponowne uruchomienie main()
.
public class SimpleTest {
public static void main(String[] args) {
Object obj = new Object();
// This calls toString() which calls hashCode() which calls os::random()
System.out.println(obj);
}
}
Jak wyjście być taka sama za każdym razem, gdy hashCode()
jest rzeczywiście os::random()
?
java -version
daje
java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b25)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)
Uwaga:
Gdyby ktoś zapytać się co System.out.println(obj);
, który nazywa obj.toString()
jeśli obiekt jest niezerowe i produkuje coś [email protected]
, musi z hashCode()
: Część po @
jest kodem mieszania obiektu w szesnastkowy (i nie ma związku z lokalizacją obiektu w pamięci, contrary do tego, co sugeruje dokumentacja, co doprowadziło do misunderstandings).
'os :: random()' będzie deterministyczne. Zawsze musi zaczynać się od tego samego początkowego materiału siewnego. – EJP
Ah, założyłem, że seed jest bieżącym czasem w milisekundach (tak jak w przypadku 'Random' Java) –
Zarodkiem metody jest początkowo' 1'. Zakładając, że nie zostanie zmieniony, pierwszą wartością będzie zawsze "mod (16807 * 1) (2 ** 31-1)". Następnie następne nasienie opiera się na tym i tak dalej. Nie znam wystarczającej liczby wewnętrznych elementów JVM, aby określić, czy to wszystko z tego powodu, czy też jest coś więcej. – Obicere