如何在JVM确保System.identityHashCode()将永远不会改变?如何在JVM确保S

2019-05-14 06:38发布

通常的默认实现Object.hashCode()是对象在内存中的地址分配的一些功能(虽然这不是由JLS规定)。 鉴于VM分流有关的对象在内存中,为什么返回的值System.identityHashCode()从来没有对象的生命周期中的变化?

如果是“一次性”的计算(该对象的hashCode时计算一次,并在对象头或东西藏起来),那么这是否意味着有可能两个对象具有相同的identityHashCode (如果他们碰巧被首先分配在内存中的地址相同)?

Answer 1:

现代JVM保存在对象头中的值。 相信值通常只计算在第一次使用,以保持在对象分配花费的最小时间(有时下降到低达一打循环)。 常见的太阳JVM可以被编译,这样的标识哈希代码始终是1对所有对象。

多个对象可以具有相同身份的散列码。 这是哈希码的性质。



Answer 2:

在回答第二个问题,不论实施的,有可能多个对象具有相同的identityHashCode。

参见错误6321873关于在javadoc中的措辞简短的讨论和程序来证明的非唯一性。



Answer 3:

在热点的对象的标头由一类指针和一个“标志”字。

为标志字中的数据结构的源代码可以发现markOop.hpp文件。 在这个文件中,有标记词的注释,描述内存布局:

hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)

在这里,我们可以看到,对于普通的Java的身份哈希码在32位系统被保存在标记字对象,它是25位长。



Answer 4:

用于实现散列函数的一般原则是:

  • 相同的对象应返回一致的hashCode,它不应该随时间变化或依赖于任何可变信息(例如,由可变构件字段的随机数或值接种的算法
  • 散列函数应具有良好的随机分布 ,和我的意思是,如果你考虑的哈希码为桶,2个对象应映射到不同的桶(哈希码)尽可能。 这2个对象将具有相同的哈希码的可能性,应该是罕见的-虽然它可能发生。


Answer 5:

据我所知,这是实现返回参考,永远不会在一个对象一生改变。



文章来源: How does the JVM ensure that System.identityHashCode() will never change?