Review Request: Add ClassOption.STRONG and default is unspecified
David Holmes
david.holmes at oracle.com
Thu Mar 12 02:26:52 UTC 2020
On 12/03/2020 9:05 am, Mandy Chung wrote:
> On 3/11/20 3:34 PM, David Holmes wrote:
>> Hi Mandy,
>>
>> On 12/03/2020 8:12 am, Mandy Chung wrote:
>>> Webrev:
>>> http://cr.openjdk.java.net/~mchung/valhalla/webrevs/hidden-classes/weak-strong-class/
>>>
>>>
>>> Alex suggests to keep the default unspecified, which I think it's a
>>> great suggestion such that people do not have to rely on the
>>> implementation assumption.
>>
>> I think this is making things unnecessarily awkward. The suggestion
>> from yesterday (as per below) was to change the default to be weak,
>> and allow people to ask for strong. That would involve simply changing
>> all WEAK to STRONG through the existing code. Now we have WEAK and
>> STRONG that are mutually exclusive so have to check for them both
>> being set, and if neither is set then we fall into
>> implementation-specific behaviour.
>> If it is insisted that we have both WEAK and STRONG then we can
>> achieve having the default unspecified by requiring that one of them
>> always be passed in.
>
> There are cases that the library code does not care.
I am skeptical of that. If you do the analysis and determine that you
don't need a strong connection then actually getting a strong connection
will work fine but may lead to footprint issues. If you don't need a
strong connection I don't see why you would choose to let it default
rather than selecting weak. If you select weak and find there is a
performance issue then you would switch to strong, comment why, and file
a RFE to fix the performance issue. I just don't see "don't care" coming
into this. And of course if you need strong then allowing it to default
is just broken!
> Note that the main motivation to allow a hidden class be strongly
> referenced because of our current implementation. It creates a
> ClassLoaderData per weak class that may result in fragmentation and
> incur bad performance overhead.
That sounds like a deficiency in the VM that should be addressed.
> This is solely implementation detail. Other VM implementation may favor
> weak classes. An implementation-specific default will give flexibility
> to the developers (not to specify neither strong or weak) to choose
> whatever performs best when running on a VM implementation.
Again I just don't buy that developers will write code that way. No one
wants to depend on the performance characteristics of a default that
could change on every release.
David
-----
> Mandy
>
>> But I much prefer what was suggested previously: either default is
>> strong and you can ask for weak; or default is weak and you can ask
>> for strong.
>>
>> Sorry.
>>
>> David
>>
>>> This patch adds a new ClassOption::STRONG enum constant while keeping
>>> ClassOption::WEAK.
>>
>>> Mandy
>>>
>>> On 3/10/20 9:55 PM, John Rose wrote:
>>>> I agree with Alex. Class loaders map names to classes. It’s not
>>>> natural *semantically* for a nameless class to have its lifetime
>>>> determined by a class loader. It may be more natural *in our
>>>> JVM implementation* (hence more performant, in the *current*
>>>> implementation) to have a non-weak link, but let’s do this only
>>>> if users request it explicitly.
>>>>
>>>> On Mar 10, 2020, at 4:55 PM, Mandy Chung <mandy.chung at oracle.com
>>>> <mailto:mandy.chung at oracle.com>> wrote:
>>>>>
>>>>> Brian, John, et al,
>>>>>
>>>>> Alex has given his feedback on the weak class feature (attached).
>>>>>
>>>>> Alex recommends to change the default of hidden classes be weak
>>>>> classes and introduce a ClassOption::STRONG option if it wants to
>>>>> ensure that the hidden class is not being reclaimed until the class
>>>>> loader becomes unreachable. See more details below.
>>>>>
>>>>> We tried to keep a hidden class be a normal class from JVM's point
>>>>> of view. Classes in the VM implementation have the same lifecycle
>>>>> as the defining class loader. In addition, LambdaForms and Nashorn
>>>>> are the only JDK use of hidden weak classes. All others such as
>>>>> lambda metafactory and string concat use hidden (strong) classes as
>>>>> they are part of the target class' internal implementation and
>>>>> should be unloaded altogether. Hence strong reference to hidden
>>>>> classes is the default.
>>>>>
>>>>> What's your recommendation?
>>>>>
>>>>> Mandy
>>>>>
>>>>>
>>>>> -------- Forwarded Message --------
>>>>> Subject: Weak references to hidden classes
>>>>> Date: Tue, 10 Mar 2020 16:16:50 -0700
>>>>> From: Alex Buckley <alex.buckley at oracle.com>
>>>>> Organization: Oracle Corporation
>>>>> To: Mandy Chung <mandy.chung at oracle.com>
>>>>>
>>>>>
>>>>>
>>>>> JEP 371 says that a hidden class may be weakly referenced by its
>>>>> class loader. Which loader? The only loader with any connection to
>>>>> a hidden class is the loader nominated to serve as the defining
>>>>> loader by the API spec of defineHiddenClass. However, that spec
>>>>> doesn't say "The defining loader holds a strong reference to the
>>>>> hidden class" because no spec says anything about how a class
>>>>> loader refers to a class.
>>>>>
>>>>> (The only relationship we do specify is the other way around --
>>>>> ClassLoader says "Every Class object contains a reference to the
>>>>> ClassLoader that defined it." -- and happily that relationship
>>>>> holds for a hidden class too.)
>>>>>
>>>>> Point is, it's odd for defineHiddenClass to standardize how a class
>>>>> loader refers to a hidden class when, conceptually, class loaders
>>>>> are not meant to "know" about hidden classes.
>>>>>
>>>>> (The connection between a defining loader and a hidden class is a
>>>>> mere accounting trick done to support the hidden class's own code.
>>>>> No class loader, not even that defining loader, knows how to
>>>>> respond to a class load request for the hidden class.)
>>>>>
>>>>> It's especially odd for defineHiddenClass's default to be a strong
>>>>> reference. That default aligns with ClassLoader::defineClass, the
>>>>> API we're trying to avoid, and doesn't align with
>>>>> Unsafe::defineAnonymousClass, the API we're trying to recreate!
>>>>>
>>>>> I understand there are performance reasons to want a loader to use
>>>>> a strong reference rather than a weak reference. Accepting that
>>>>> claim, I recommend having the implementation use a weak reference
>>>>> by default, having the spec allow that, then introducing
>>>>> ClassOption.STRONG to force a strong reference. That is, specify that:
>>>>>
>>>>> "In the absence of an option, the defining loader's relationship
>>>>> with the hidden class is unspecified, and the loader implementation
>>>>> may use a strong reference or a weak reference to keep track of the
>>>>> hidden class. If a hidden class is not strongly referenced by the
>>>>> class loader which is deemed to be its defining loader, then the
>>>>> hidden class can be unloaded when library code no longer refers to
>>>>> it. Library developers who wish to prevent the hidden class from
>>>>> being unloaded must ensure that its Class object is never
>>>>> reclaimed, or else use the ClassOption.STRONG option."
>>>>>
>>>>> I understand there is a concern that developers would not realize /
>>>>> be surprised by getting a weak reference as the default
>>>>> implementation. However, the planet-wide audience for
>>>>> defineHiddenClass is perhaps 500 developers. They already have to
>>>>> know what they're doing because the features of hidden classes are
>>>>> already more limited than the features of VM-anonymous classes.,
>>>>> e.g., no constant pool patching. The usual "Java should save
>>>>> developers from making silly mistakes" rule doesn't apply here.
>>>>>
>>>>> Alex
>>>>
>>>
>
More information about the valhalla-dev
mailing list