通常, Object.hashCode()
的默认实现是内存中对象的已分配地址的某些功能(尽管 JLS 并未强制执行此操作)。鉴于VM在内存中分流对象,为什么 System.identityHashCode()
返回的值在对象的生命周期内永远不会改变?
如果是“一次性”计算(对象的hashCode
计算一次并藏在对象标题或其他内容中),那么这是否意味着两个对象可能具有相同的{{ 1}}(如果它们碰巧首先在内存中的同一地址分配)?
答案 0 :(得分:38)
现代JVM将值保存在对象标头中。我认为该值通常仅在首次使用时计算,以便将在对象分配中花费的时间保持在最小值(有时低至十几个周期)。可以编译公共Sun JVM,以便所有对象的标识哈希码始终为1。
多个对象可以具有相同的标识哈希码。这就是哈希码的本质。
答案 1 :(得分:16)
在回答第二个问题时,无论实现如何,多个对象都可以具有相同的identityHashCode。
请参阅bug 6321873,了解javadoc中措词的简要讨论,以及展示非唯一性的程序。
答案 2 :(得分:2)
HotSpot中对象的标题由类指针和“标记”字组成。
标记字的数据结构的源代码可以在markOop.hpp
文件中找到。在此文件中有一条描述标记字的内存布局的注释:
hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)
在这里我们可以看到32位系统上普通Java对象的标识哈希码保存在标记字中,长度为25位。
答案 3 :(得分:0)
实现散列函数的一般准则是:
答案 4 :(得分:-3)
据我所知,这是为了返回引用而实现的,该引用在对象生存期内永远不会改变。