Como é que a JVM garantir que System.identityHashCode () nunca vai mudar?
-
21-08-2019 - |
Pergunta
Normalmente, a implementação padrão de Object.hashCode()
é alguma função do endereço alocado do objeto na memória (embora este não é mandatado pelo JLS ). Dado que os objetos da VM derivações sobre na memória, por que o valor retornado pelo System.identityHashCode()
nunca mudam durante a vida do objeto?
Se é um cálculo "one-shot" (hashCode
do objeto é calculado uma vez e escondido no cabeçalho do objeto ou algo assim), então isso significa que é possível que dois objetos para ter o mesmo identityHashCode
(se acontecer de ser primeiro alocados no mesmo endereço na memória)?
Solução
Modern JVMs salvar o valor no cabeçalho do objeto. Eu acredito que o valor é normalmente calculado apenas na primeira utilização, a fim de manter o tempo gasto na alocação de objeto a um mínimo (às vezes para baixo para tão baixo quanto uma dúzia de ciclos). O comum Sun JVM pode ser compilado para que o código de identificação de hash é sempre 1 para todos os objetos.
Vários objetos podem ter o mesmo código de identificação hash. Essa é a natureza dos códigos de hash.
Outras dicas
Em resposta à segunda questão, independentemente da realização, é possível que vários objetos para ter o mesmo identityHashCode.
Consulte bug 6.321.873 para uma breve discussão sobre a formulação do javadoc, e um programa para demonstrar a não-singularidade.
O cabeçalho de um objeto no HotSpot consiste em um ponteiro de classe e uma palavra "marca".
O código fonte da estrutura de dados para a palavra marca pode ser encontrada a markOop.hpp
arquivo. Nesse arquivo há um layout de memória comentário descrevendo da palavra marca:
hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)
Aqui podemos ver que o código a identidade de hash para Java normal de objetos em um sistema de 32 bits é guardado na marca nominativa e é 25 bits de comprimento.
A orientação geral para a implementação de uma função hash é:
-
o mesmo objecto deve retornar um hashCode consistente , que não deve mudar com o tempo ou dependem de alguma informação variável (por exemplo, um algoritmo semeadas por um número ou valores de campos membro mutável aleatória - a função hash deve ter uma boa distribuição aleatória , e com isso quero dizer, se você considerar o hashcode como baldes, 2 objetos devem mapear para diferentes baldes (hashcodes) na medida do possível. A possibilidade de que 2 objetos teria o mesmo código hash deve ser raro - embora pode acontecer.
Tanto quanto eu sei, isso é implementado para retornar a referência, que nunca mudam num objetos vida.