RFC (round 1), JEP draft: Low-level Object layout introspection methods
brian.goetz at oracle.com
Tue Aug 11 13:17:56 UTC 2020
> I think we need to get one thing very straight: these are best-effort informational APIs.
I accept that this is the motivation, and for things like
`estimateDeepSizeOf`, I think the world will go along with your plan.
On the other hand, the intention of `Unsafe` was that Doug would
effectively be the only user, ever, and we see how well that worked
out. So the best of intentions don't always predict future reality, and
hence sometimes we need to be cynical jerks. (At your service!)
> But I disagree with this part. I don't think the existence of the best-effort informational APIs
If that really described the widespread perception, I would agree with
you. But I simply do not believe there is any way to expose an
addressOf method and have it widely accepted as merely "best-effort".
It is a perfect example of an "attractive nuisance"
erecting a sign that says "no swimming" will not keep the kids out of
> I guess the real question is where to put something that goes beyond the "pure Java" and provides
> the implementation details. So it could avoid the impression of telling "pure Java" facts? I put
> prototype methods in Runtime, because that looked like one of the least "pure Java" facilities. I'd
> be happy to learn some other place where such API can be put :)
The obvious first answer is: "not in the JDK." Even if the JDK layout
algorithm is a closely guarded secrete, a fortune teller down the street
can surely offer predictions about likely future layouts. And wary
consumers can decide whether or not they want to trust the safety of
their applications to such sayers of sooth. The second answer is: "not
in the JDK, yet." It is quite possible that, when we get farther down
the road of making Unsafe unnecessary, new options will be available to us.
> With my JEP author hat on: JEP caters for low-level introspection use case, such as JOL and JAMM. It
> does not intend to cater for "low-level hackery for accessing the Java heap", and it tries to
> specifically make the argument that new APIs do not allow this low-level hackery beyond what is
> possible today and in a foreseeable future.
I believe that your intentions are pure! But we both know that purest
of intentions are not enough to avoid trouble.
> Let me ask the specific question: which APIs do you like, and which do
> you dislike?
> I gather you like:
> public static long sizeOf(Object obj);
> public static long deepSizeOf(Object obj);
> public static long deepSizeOf(Object obj, ToLongFunction<Object> includeCheck);
> ...but dislike:
> public static long addressOf(Object obj);
> public static long fieldOffsetOf(Field field);
> ...and it is not clear what is your position on:
> public static long fieldSizeOf(Field field);
I would prefix all the ones I like with `estimate`, to make it crystal
clear. (There is precedent for this convention in the JDK; see
Spliterator.) I don't see any immediate attractive-nuisance problem
with `estimateFieldSize`, which gets more interesting when we get to
inline classes, though I'd want to think about it further. (On the
other hand, `estimateFieldSize` encourages a new possibly-incorrect
assumption: that all the bits of a field are guaranteed to be
contiguous, which is certainly true for today's nine basic types, and
true for the prototype of Valhalla, but might not be true forever.)
To put it another way, the reason that `deepSizeOf` is unobjectionable
is that no one who has thought about the problem in any depth would be
tempted to believe it, because almost anyone in the position of tuning
cache eviction metrics is aware that this is an impossible problem (even
in C -- we might know struct sizes exactly, but we have no idea to what
degree pointers are aliased, and that matters a lot for this problem.)
But given that the next-best available cost metrics are atrocious,
something merely not-terrible is a big improvement. On the other hand,
I do not believe one could ever make a similar credible argument like
this for `addressOf` or `fieldOffset` that "no one would ever try to map
this directly to reality." (That wasn't a challenge.)
More information about the jdk-dev