On Tue, 21 Feb 2023 23:44:48 GMT, David Holmes <dhol...@openjdk.org> wrote:

> I also have to disagree with the statement. The unit of unloading is the 
> ClassLoader.

Hidden classes are not normal classes. They are not defined, created or loaded 
by a class loader. The only reason why hidden classes maintain a link to a 
*defining class loader* is because they need it to resolve types used by the 
hidden class's own fields and methods.
 
Some references from [JEP 371: Hidden Classes](https://openjdk.org/jeps/371):

> Dynamically generated classes may only be needed for a limited time, so 
> retaining them for the lifetime of the statically generated class might 
> unnecessarily increase memory footprint. Existing workarounds for this 
> situation, such as per-class class loaders, are cumbersome and inefficient.

> A hidden class can be unloaded when it is no longer reachable, or it can 
> share the lifetime of a class loader so that it is unloaded only when the 
> class loader is garbage collected

> A hidden class is not created by a class loader and has only a loose 
> connection to the class loader deemed to be its defining loader. We can turn 
> these facts to our advantage by allowing a hidden class to be unloaded even 
> if its notional defining loader cannot be reclaimed by the garbage collector.

> By default, Lookup::defineHiddenClass will create a hidden class that can be 
> unloaded regardless of whether its notional defining loader is still alive. 
> That is, when all instances of the hidden class are reclaimed and the hidden 
> class is no longer reachable, it may be unloaded even though its notional 
> defining loader is still reachable. This behavior is useful when a language 
> runtime creates a hidden class to serve multiple classes defined by arbitrary 
> class loaders: The runtime will see an improvement in footprint and 
> performance relative to both `ClassLoader::defineClass()` and 
> Unsafe::defineAnonymousClass()`

The only reason why hidden classes created by `LambdaMetaFactory` are strongly 
linked to a class loader (at least I haven't heard any other argument until now 
in this thread) is to *save native memory* and not because it is *logically 
required*! It's fine for me if you don't want to fix that. I can just not 
understand why you are all still insisting that creating a new ClassLoaderData 
object per hidden class is such a great decision and fixing that would not be 
beneficial.

Hidden classes were designed to be light-weight and easily unloadable (see JEP 
references above). In the case of `LambdaMetaFactory` we unnecessarily link 
them strongly to a class loader just because the current implementation is too 
expensive otherwise. On a side note, the JDK already creates non-strongly 
linked hidden classes as well, e.g. for 
`java.lang.invoke.MethodHandles$Lookup.unreflect()`.

-------------

PR: https://git.openjdk.org/jdk/pull/12493

Reply via email to