Fork me on GitHub

Does anyone happen to know how JVMs implement returning a consistent .hashCode for an object like a Clojure ref or atom that pretty much has a mutable reference as its only contents? It shouldn't be based upon the object's current address in memory, since garbage collection can change that over time. I know it is not calculated based upon the contents of the mutable reference, because .hashCode is supposed to be stable for the lifetime of the same object. I know I can create 10,000 atoms and they usually all have unique .hashCode values. Does the JVM just create some "counter" or "pseudo-random seed" value it stores in all newly created objects, and include that in the default Object class implementation of .hashCode?


@andy.fingerhut yeah most VMs have a way of doing this


in PyPy it's done by allocating some objects in the old gen so they don't move


but I'm sure the JVM does somethign else


So this counter/seed becomes part of the overhead of every JVM Object, I guess?


yes, the overhead per ojbect in the JVM is 2 pointers,


so it might be in there


makes sense. Thanks


why is that a thing ^^ ?


Google search helped me find this article with probably more details than I will ever recall:


OpenJDK apparently has a config choice of 6 different ways, the default one in some OpenJDK versions being a pseudo-random number, and OpenJDK8 and later use "Thread state combined with xorshift". In any case, it is a field stored in every Object instance.


@tbaldridge You are asking why it is a native method, or something else? If the native thing, I don't know why that would be important.


no, I was surprised to find an entire wikipedia article on .hashCode


Eh, it seems about as important as many other things there are wikipedia articles for. I am all for proliferation of Wikipedia articles ad nauseum 🙂

Alex Miller (Clojure team)21:05:25

probably started with a conversation just like this

👍 8

Especially if it is on a topic I want to read about some day.


The article I linked makes me glad that I don't work on JVM optimizations - some of the "overhead" data in Object instances can apparently change over time based upon things like which threads currently have it locked (due to an optimization called 'biased locking', which the brief description makes sense why it could speed things up in the common case, but wow it doesn't look fun to debug bugs in such code).