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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1063068/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 15:00:37  来源:igfitidea点击:

How does the JVM ensure that System.identityHashCode() will never change?

javajvmhashcodeheap-memory

提问by butterchicken

Typically the default implementation of Object.hashCode()is some function of the allocated address of the object in memory (though this is not mandated by the JLS). Given that the VM shunts objects about in memory, why does the value returned by System.identityHashCode()never change during the object's lifetime?

通常, 的默认实现Object.hashCode()是内存中对象的分配地址的某些函数(尽管这不是JLS强制要求的)。鉴于 VM 在内存中分流对象,为什么返回的值System.identityHashCode()在对象的生命周期内永远不会改变?

If it is a "one-shot" calculation (the object's hashCodeis calculated once and stashed in the object header or something), then does that mean it is possible for two objects to have the same identityHashCode(if they happen to be first allocated at the same address in memory)?

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

采纳答案by Tom Hawtin - tackline

Modern JVMs save the value in the object header. I believe the value is typically calculated only on first use in order to keep time spent in object allocation to a minimum (sometimes down to as low as a dozen cycles). The common Sun JVM can be compiled so that the identity hash code is always 1 for all objects.

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

Multiple objects can have the same identity hash code. That is the nature of hash codes.

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

回答by Stephen Denne

In answer to the second question, irrespective of the implementation, it is possible for multiple objects to have the same identityHashCode.

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

See bug 6321873for a brief discussion on the wording in the javadoc, and a program to demonstrate non-uniqueness.

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

回答by Lii

The header of an object in HotSpot consists of a class pointer and a "mark" word.

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

The source code of the data structure for the mark word can be found the markOop.hppfile. In this file there is a comment describing memory layout of the mark word:

标记词的数据结构的源代码可以在markOop.hpp文件中找到。在这个文件中有一个注释描述了标记词的内存布局:

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

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

Here we can see that the the identity hash code for normal Java objects on a 32 bit system is saved in the mark word and it is 25 bits long.

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

回答by Gishu

The general guideline for implementing a hashing function is :

实现散列函数的一般准则是:

  • the same object should return a consistent hashCode, it should not change with time or depend on any variable information (e.g. an algorithm seeded by a random number or values of mutable member fields
  • the hash function should have a good random distribution, and by that I mean if you consider the hashcode as buckets, 2 objects should map to different buckets (hashcodes) as far as possible. The possibility that 2 objects would have the same hashcode should be rare - although it canhappen.
  • 同一个对象应该返回一致的 hashCode,它不应该随时间变化或依赖于任何变量信息(例如由随机数或可变成员字段值播种的算法
  • 散列函数应该具有良好的随机分布,我的意思是如果您将散列码视为桶,则 2 个对象应尽可能映射到不同的桶(散列码)。2 个对象具有相同哈希码的可能性应该很少 - 尽管它可能发生。

回答by Mnementh

As far as I know, this is implemented to return the reference, that will never change in a objects lifetime .

据我所知,这是为了返回引用,在对象生命周期中永远不会改变。