JVM如何确保System.identityHashCode()永远不会更改?

ryhaxcpt  于 4个月前  发布在  其他
关注(0)|答案(5)|浏览(46)

通常情况下,Object.hashCode()的默认实现是对象在内存中的分配地址的函数(尽管Java语言规范并没有强制要求)。既然VM在内存中分流对象,为什么System.identityHashCode()返回的值在对象的生命周期内从未改变?
如果它是一个“一次性”计算(对象的hashCode只计算一次,并隐藏在对象头部或其他地方),那么这是否意味着两个对象可能具有相同的identityHashCode(如果它们碰巧首先分配在内存中的相同地址)?

3npbholx

3npbholx1#

现代JVM将值保存在对象头中。我相信该值通常只在第一次使用时计算,以便将对象分配花费的时间保持在最低限度(有时低至十几个周期)。常见的Sun JVM可以编译为所有对象的身份哈希代码始终为1。
多个对象可以有相同的标识哈希码,这就是哈希码的本质。

krcsximq

krcsximq2#

在回答第二个问题时,无论实现如何,多个对象都可能具有相同的identityHashCode。
请参阅bug 6321873以获得关于javadoc中措辞的简要讨论,以及演示非唯一性的程序。

z9ju0rcb

z9ju0rcb3#

HotSpot中对象的头由一个类指针和一个“标记”字组成。
标记字的数据结构的源代码可以在markOop.hpp文件中找到。在这个文件中有一个注解,描述了标记字的内存布局:
hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)
这里我们可以看到,在32位系统上,普通Java对象的身份哈希码保存在标记字中,长度为25位。

qzwqbdag

qzwqbdag4#

实现哈希函数的一般准则是:

*同一个对象应该返回一个一致的hashCode,它不应该随着时间的推移而改变,也不应该依赖于任何变量信息(例如,由随机数或可变成员字段的值作为种子的算法

  • 散列函数应该有一个良好的随机分布,我的意思是,如果你把散列代码看作桶,2个对象应该尽可能Map到不同的桶(散列代码)。2个对象具有相同散列代码的可能性应该是罕见的-尽管它**可能发生。
2guxujil

2guxujil5#

据我所知,这是实现返回引用,这将永远不会改变在一个对象的生命周期。

相关问题