RFC (round 1), JEP draft: Low-level Object layout introspection methods

Brian Goetz 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" 
(https://en.wikipedia.org/wiki/Attractive_nuisance_doctrine). Merely 
erecting a sign that says "no swimming" will not keep the kids out of 
the pool.

> 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 mailing list