如果在HotSpot Java 7 64位版本上运行以下命令.
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);
Run Code Online (Sandbox Code Playgroud)
你可以得到像这样的结果
The count of negative hashCodes was 0, the count of odd hashCodes was 49994232
Run Code Online (Sandbox Code Playgroud)
我想知道这是否意味着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 }
Run Code Online (Sandbox Code Playgroud)
NPE*_*NPE 13
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;
}
Run Code Online (Sandbox Code Playgroud)
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),
Run Code Online (Sandbox Code Playgroud)
如您所见,markOopDesc::hash_mask始终将第31位设置为零.
至于为什么这样做,你的猜测和我的一样好.可能是原始开发人员认为只处理正整数会简化事情.就我们所知,它甚至可能是hash_bits计算中的一个错误.;-)
| 归档时间: |
|
| 查看次数: |
544 次 |
| 最近记录: |