21

HotSpot Java764ビットバージョンで以下を実行する場合。

int countTopBit = 0, countLowestBit = 0;
for (int i = 0; i < 100000000; i++) {
    int h = new Object().hashCode();
    if (h < 0)
        countTopBit++;
    if ((h & 1) == 1)
        countLowestBit++;
}
System.out.println("The count of negative hashCodes was " + countTopBit + ", the count of odd hashCodes was " + countLowestBit);

あなたは次のような結果を得ることができます

The count of negative hashCodes was 0, the count of odd hashCodes was 49994232

これはObject.hashCode()本当に31ビットしかないのか、なぜそうなるのか疑問に思いました。


トップビットが使用されていないわけではありません。HashMapのソースから

257   /**
258    * Applies a supplemental hash function to a given hashCode, which
259    * defends against poor quality hash functions.  This is critical
260    * because HashMap uses power-of-two length hash tables, that
261    * otherwise encounter collisions for hashCodes that do not differ
262    * in lower bits. Note: Null keys always map to hash 0, thus index 0.
263    */
264   static int hash(int h) {
265       // This function ensures that hashCodes that differ only by
266       // constant multiples at each bit position have a bounded
267       // number of collisions (approximately 8 at default load factor).
268       h ^= (h >>> 20) ^ (h >>> 12);
269       return h ^ (h >>> 7) ^ (h >>> 4);
270   }
4

1 に答える 1

14

HotSpot は、 のさまざまなハッシュ アルゴリズムをサポートしていObjectます。経験的に発見したように、結果が返される前に最上位ビットが常にマスクされます。

// src/share/vm/runtime/synchronizer.cpp
static inline intptr_t get_next_hash(Thread * Self, oop obj) {
   ...
   value &= markOopDesc::hash_mask;
   ...
   return value;
}

markOopDesc::hash_maskは次のように計算されます。

  enum { age_bits                 = 4,
         lock_bits                = 2,
         biased_lock_bits         = 1,
         max_hash_bits            = BitsPerWord - age_bits - lock_bits - biased_lock_bits,
         hash_bits                = max_hash_bits > 31 ? 31 : max_hash_bits,
         ...
         hash_mask               = right_n_bits(hash_bits),

ご覧のとおり、markOopDesc::hash_mask常にビット 31 がゼロに設定されています。

なぜこれが行われるのかについては、あなたの推測は私の推測と同じです。元の開発者は、正の整数のみを処理することで物事が簡単になると感じていた可能性があります。私たちが知っている限りでは、それはhash_bits計算の 1 つずれのエラーでさえある可能性があります。;-)

于 2013-01-21T09:44:15.687 に答える