问题描述
我经常听说这些方法( Object.hashCode
和 System.identityHashCode
)返回地址对象,或从地址中快速计算出来的东西;但我也很确定垃圾收集器移动并压缩对象。由于哈希码不能改变,所以会出现问题。我知道这不是日常工作中需要知道的,但我想了解内部。那么,有没有人知道这是如何在Java中实现的?或.NET,因为它们可能是相似的。
.NET的实现是故意不发布的(当你尝试反编译它时,你会发现它使得一个非托管的框架调用)。这样的唯一文档是,其中仅指出它不能保证为每个对象产生不同的值,并且可能会在不同的框架版本之间改变。对它的实际工作方式作出任何假设可能是不明智的。
Java被更好理解(虽然大概可能会在JVM之间有所不同),并且在问题:
Java实现的要点是,通过契约,对象的哈希码的值直到它第一次检索。之后,它必须保持不变。因此,在第一次调用对象的hashcode()方法之前,移动对象的GC并不重要。之后,使用缓存的值。
I've often heard that these methods (Object.hashCode
and System.identityHashCode
) return the address of the object, or something computed quickly from the address; but I'm also pretty sure the garbage collector moves and compacts objects. Since the hash code cannot change, this presents a problem. I know this is not something one needs to know for everyday work, but I'd like to understand the internals. So, does anyone know how this is implemented in Java? Or .NET, since they are probably similar.
.NET's implementation is intentionally not published (and when you attempt to decompile it, you will find that it makes an unmanaged framework call). The only documentation as such is here, which only states that it is "not guaranteed to produce a different value for each object", and "may change between framework versions". Making any assumptions about how it actually works is probably ill-advised.
Java's is more well-understood (though presumably could differ across JVMs), and is covered specifically in this question: Will .hashcode() return a different int due to compaction of tenure space?
The gist of the Java implementation is that by contract, the value of an object's hashcode is not relevant until it is retrieved for the first time. After that, it must remain constant. Thus the GC moving the object doesn't matter until the object's hashcode() method is called for the first time. After that, a cached value is used.
这篇关于如果Java的垃圾收集器移动对象,什么是Object.hashCode和System.identityHashCode?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!