web-dev-qa-db-ja.com

JVMはどのようにしてSystem.identityHashCode()が変更されないようにしていますか?

通常、Object.hashCode()のデフォルトの実装は、メモリ内のオブジェクトに割り当てられたアドレスの関数です(ただし、[〜 #〜] jls [〜#〜])。 VMがメモリ内のオブジェクトを回避する場合、なぜSystem.identityHashCode()によって返される値がオブジェクトの存続期間中に変更されないのですか?

「ワンショット」計算(オブジェクトのhashCodeが一度計算され、オブジェクトヘッダーなどに格納される)の場合、2つのオブジェクトが同じidentityHashCode(メモリ内の同じアドレスに最初に割り当てられた場合)?

68
butterchicken

最新のJVMは、値をオブジェクトヘッダーに保存します。この値は通常、オブジェクトの割り当てに費やされる時間を最小限(場合によっては12サイクル程度)に保つために、最初の使用時にのみ計算されると思います。一般的なSun JVMは、すべてのオブジェクトのIDハッシュコードが常に1になるようにコンパイルできます。

複数のオブジェクトが同じIDハッシュコードを持つことができます。それがハッシュコードの性質です。

40

2番目の質問への回答では、実装に関係なく、複数のオブジェクトが同じidentityHashCodeを持つ可能性があります。

Javadocの表現についての簡単な説明と、一意でないことを示すプログラムについては、 バグ632187 を参照してください。

16
Stephen Denne

ハッシュ関数を実装するための一般的なガイドラインは次のとおりです。

  • 同じオブジェクトは一貫したhashCodeを返す必要があります、それは時間とともに変化したり、変数情報(たとえば、乱数または可変メンバーフィールドの値によってシードされたアルゴリズム)に依存したりすることはできません
  • ハッシュ関数には良いランダム分布が必要です。つまり、ハッシュコードをバケットと見なす場合、2つのオブジェクトは可能な限り異なるバケット(ハッシュコード)にマップする必要があります。 2つのオブジェクトが同じハッシュコードを持っている可能性はまれです-ただし、canが発生します。
0
Gishu