37

我经常听说这些方法 (Object.hashCodeSystem.identityHashCode) 返回对象的地址,或者从地址快速计算出来的东西;但我也很确定垃圾收集器会移动和压缩对象。由于哈希码不能改变,这就带来了一个问题。我知道这不是日常工作需要知道的事情,但我想了解内部情况。那么,有谁知道这是如何在 Java 中实现的?或 .NET,因为它们可能相似。

4

3 回答 3

26

.NET 的实现是故意不发布的(当您尝试反编译它时,您会发现它进行了非托管框架调用)。唯一的文档是这里,它只声明“不能保证为每个对象产生不同的值”,并且“可能会在框架版本之间发生变化”。对它的实际工作方式做出任何假设可能都是不明智的。

Java 更容易理解(尽管可能在不同的 JVM 中可能有所不同),并且在这个问题中特别提到:Will .hashcode() return a different int due to compaction of tenure space?

Java 实现的要点是,按照约定,对象的哈希码的值在第一次检索之前是不相关的。之后,它必须保持不变。因此,在第一次调用对象的 hashcode() 方法之前,移动对象的 GC 并不重要。之后,使用缓存值。

于 2011-08-26T15:53:53.817 回答
3

对象的 identityHashCode 不会改变。因此,任何移动都在该水平之下进行。

一个基本的实现将有一个逻辑地址 --> 每个对象的物理地址映射。

更复杂的实现只会在页面级别进行映射,因此最后 6 位可能是内存偏移量,其余的是页面 ID。间接将发生在页面 id --> 实际页面地址级别。

于 2011-08-26T15:54:32.297 回答
1

在 .net 中,getHash() 方法会受到 GC 的影响,因此建议开发人员使用自己的哈希实现。我现在找不到内部实现的链接。以后找到的话我会发的。。

找到链接......这个问题在这里得到了回答

于 2011-08-26T15:51:41.533 回答