[10] RFR: 8184603: Create ObjectStreamField signature lazily when possible

Peter Levart peter.levart at gmail.com
Sat Jul 15 12:08:43 UTC 2017


On 07/14/2017 04:22 PM, Aleksey Shipilev wrote:
> On 07/14/2017 04:12 PM, Claes Redestad wrote:
>>> Thing is, "volatile" is not as strong as "final" for racy initializations:
>>> https://shipilev.net/blog/2016/close-encounters-of-jmm-kind/#wishful-volatiles-are-finals
>>> If that is not a concern -- e.g. if private constructor is never used to make
>>> shared OSFs -- then "volatile" is superfluous. If it is a concern, then
>>> "volatile" is not enough, and you have to keep "final".
>> Gosh!
>> Seeing how it's possible to lookup ObjectStreamClass and get at
>> ObjectStreamField's that might have been created from the internal
>> constructors, I think it *is* a concern.
>> Thus the only viable option that allows us to be correct *and* lazy might be to
>> add a new field that is lazily initialized only when using the public constructors:
>> http://cr.openjdk.java.net/~redestad/8184603/jdk.02/
> I think this is fine from concurrency standpoint. Not sure how safe it is to
> increase OSF footprint, that's your call! I also think the largest improvement
> would be from avoiding the intern() call in constructor -- I frequently observed
> it on the OSF hot paths. I would trade excess field for avoiding String.intern()
> any day.

It seems that interning signature(s) is important for correctness (for 
example, in ObjectOutputStream.writeTypeString(str) the 'str' is used to 
lookup a handle so that handles are put into stream instead of the type 
signature(s) for multiple references to the same type). Looking up 
objects in handles table is based on identity comparison.

But there might be a way to obtain a singleton signature String per type 
and still profit. By adding a field to java.lang.Class and caching the 
JVM signature there. This would also be a useful public method, don't 
you think?

Out of 191 ObjectStreamField constructions I found in JDK sources, there 
are only 39 distinct field types involved, so the number if intern() 
calls is reduced by a factor of ~5. There's no need to cache signature 
in ObjectStreamField(s) this way any more, but there must still be a 
single final field for ObjectStreamField(s) constructed with explicit 

Here's how this looks like in code:


What do you think?

Regards, Peter

> As Doug Lea mentions offlist, another alternative would be to do fullFence at
> the end of OSF private constructor. But, this is low-level, and relies on
> hardware that handles data-dependent loads fine on reader side (which is true
> for all arches OpenJDK targets, I think). If there is no pressing need to keep
> OSF footprint minimal, I'd avoid doing explicit fences.
> Thanks,
> -Aleksey

More information about the core-libs-dev mailing list