java.lang.Object的hashCode使用的算法究竟是什么

时间:2014-07-23 22:59:19

标签: java openjdk

JVM 中使用什么算法来实现java.lang.Object的隐式hashCode()方法?

[ OpenJDK Oracle JDK 在答案中首选]。

1 个答案:

答案 0 :(得分:5)

它依赖于实现(并且非常重要,算法完全直到实现,只要它是一致的。)但是,根据答案here,您可以看到native source file其中哈希是在OpenJDK 7中生成的(查看get_next_hash()函数),它实际上在此特定版本中指定了许多可能的算法:

// Possibilities:
// * MD5Digest of {obj,stwRandom}
// * CRC32 of {obj,stwRandom} or any linear-feedback shift register function.
// * A DES- or AES-style SBox[] mechanism
// * One of the Phi-based schemes, such as:
//   2654435761 = 2^32 * Phi (golden ratio)
//   HashCodeValue = ((uintptr_t(obj) >> 3) * 2654435761) ^ GVars.stwRandom ;
// * A variation of Marsaglia's shift-xor RNG scheme.
// * (obj ^ stwRandom) is appealing, but can result
//   in undesirable regularity in the hashCode values of adjacent objects
//   (objects allocated back-to-back, in particular).  This could potentially
//   result in hashtable collisions and reduced hashtable efficiency.
//   There are simple ways to "diffuse" the middle address bits over the
//   generated hashCode values
//

正如已经说过的那样,默认算法只是使用随机数,但是一个有趣的评论进一步指出:

// Marsaglia's xor-shift scheme with thread-specific state
// This is probably the best overall implementation -- we'll
// likely make this the default in future releases.

这类似于上面列出的可能性中提到的(obj ^ stwRandom)方法,但它通过将“特定于线程的状态”信息绑定到哈希中来解决与连续快速分配的对象相关的不必要的规则 - 因此,如果两个对象碰巧在非常相似的时间分配,因为它们被分配在同时执行的两个单独的线程上,那么输入到散列中的离散线程信息仍应确保生成离散的足够哈希值。