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

问题描述 投票:0回答:5

通常,

Object.hashCode()
的默认实现是内存中对象分配地址的某个函数(尽管Java语言规范没有强制要求)。鉴于虚拟机在内存中分流对象,为什么
System.identityHashCode()
返回的值在对象的生命周期内永远不会改变?

如果是“一次性”计算(对象的

hashCode
计算一次并隐藏在对象头或其他内容中),那么这是否意味着两个对象可能具有相同的
identityHashCode
(如果它们碰巧首先分配在内存中的同一地址)?

java jvm hashcode heap-memory
5个回答
43
投票

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

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


17
投票

回答第二个问题,无论实现如何,多个对象都可能具有相同的identityHashCode。

请参阅 bug 6321873,了解有关 javadoc 中措辞的简短讨论以及演示非唯一性的程序。


2
投票

HotSpot 中对象的标头由类指针和“标记”字组成。

标记字数据结构的源代码可以在

markOop.hpp
文件中找到。在这个文件中有一条注释描述了标记字的内存布局:

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

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


0
投票

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

  • 同一个对象应该返回一致的 hashCode,它不应该随时间变化或依赖于任何变量信息(例如,由随机数或可变成员字段值播种的算法
  • 哈希函数应该具有良好的随机分布,我的意思是,如果您将哈希码视为存储桶,则2个对象应尽可能映射到不同的存储桶(哈希码)。两个对象具有相同哈希码的可能性应该很少见——尽管它“可能”发生。

-4
投票

© www.soinside.com 2019 - 2024. All rights reserved.