如果Java的垃圾回收器移动对象,什么是Object.hashCode和System.identityHashCode?

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


答案 1

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

Java更易于理解(尽管可能在JVM之间有所不同),并且在本文中特别介绍:.hashcode()会由于任期空间的压缩而返回不同的int吗?

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


答案 2

对象的标识哈希码不会更改。因此,任何移动都是在该水平下完成的。

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

更复杂的实现将仅在页面级别具有映射,因此也许最后6位是内存偏移量,其余位是页面ID。间接寻址将发生在页面 ID -->实际页面地址级别。