通常情况下,Object.hashCode()的默认实现是对象在内存中的分配地址的函数(尽管Java语言规范并没有强制要求)。既然VM在内存中分流对象,为什么System.identityHashCode()返回的值在对象的生命周期内从未改变?如果它是一个“一次性”计算(对象的hashCode只计算一次,并隐藏在对象头部或其他地方),那么这是否意味着两个对象可能具有相同的identityHashCode(如果它们碰巧首先分配在内存中的相同地址)?
Object.hashCode()
System.identityHashCode()
hashCode
identityHashCode
3npbholx1#
现代JVM将值保存在对象头中。我相信该值通常只在第一次使用时计算,以便将对象分配花费的时间保持在最低限度(有时低至十几个周期)。常见的Sun JVM可以编译为所有对象的身份哈希代码始终为1。多个对象可以有相同的标识哈希码,这就是哈希码的本质。
krcsximq2#
在回答第二个问题时,无论实现如何,多个对象都可能具有相同的identityHashCode。请参阅bug 6321873以获得关于javadoc中措辞的简要讨论,以及演示非唯一性的程序。
z9ju0rcb3#
HotSpot中对象的头由一个类指针和一个“标记”字组成。标记字的数据结构的源代码可以在markOop.hpp文件中找到。在这个文件中有一个注解,描述了标记字的内存布局:hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)个这里我们可以看到,在32位系统上,普通Java对象的身份哈希码保存在标记字中,长度为25位。
markOop.hpp
hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)
qzwqbdag4#
实现哈希函数的一般准则是:
*同一个对象应该返回一个一致的hashCode,它不应该随着时间的推移而改变,也不应该依赖于任何变量信息(例如,由随机数或可变成员字段的值作为种子的算法
2guxujil5#
据我所知,这是实现返回引用,这将永远不会改变在一个对象的生命周期。
5条答案
按热度按时间3npbholx1#
现代JVM将值保存在对象头中。我相信该值通常只在第一次使用时计算,以便将对象分配花费的时间保持在最低限度(有时低至十几个周期)。常见的Sun JVM可以编译为所有对象的身份哈希代码始终为1。
多个对象可以有相同的标识哈希码,这就是哈希码的本质。
krcsximq2#
在回答第二个问题时,无论实现如何,多个对象都可能具有相同的identityHashCode。
请参阅bug 6321873以获得关于javadoc中措辞的简要讨论,以及演示非唯一性的程序。
z9ju0rcb3#
HotSpot中对象的头由一个类指针和一个“标记”字组成。
标记字的数据结构的源代码可以在
markOop.hpp
文件中找到。在这个文件中有一个注解,描述了标记字的内存布局:hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)
个这里我们可以看到,在32位系统上,普通Java对象的身份哈希码保存在标记字中,长度为25位。
qzwqbdag4#
实现哈希函数的一般准则是:
*同一个对象应该返回一个一致的hashCode,它不应该随着时间的推移而改变,也不应该依赖于任何变量信息(例如,由随机数或可变成员字段的值作为种子的算法
2guxujil5#
据我所知,这是实现返回引用,这将永远不会改变在一个对象的生命周期。