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

时间:2011-08-26 15:46:13

标签: java garbage-collection hashcode internals object-identity

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

3 个答案:

答案 0 :(得分:23)

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

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

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

答案 1 :(得分:3)

对象的identityHashCode不会更改。因此,任何移动都在该级别之下完成。

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

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

答案 2 :(得分:1)

在.net中,getHash()方法将受到GC的影响,因此建议开发人员使用自己的哈希实现。我无法在他们那里找到内部实施的链接。如果我发现它,我会稍后发布..

找到链接...这个问题已经回答here