Search code examples
javagarbage-collectionhashcodeinternalsobject-identity

If Java's garbage collector moves objects, what is Object.hashCode and System.identityHashCode?


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.


Solution

  • .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.