JDK-8275509: (jlink) SystemModulesPlugin generates a jdk.internal.module.SystemModules$all.class which isn't reproducible
Ioi Lam
ioi.lam at oracle.com
Fri Oct 22 06:59:37 UTC 2021
On 10/21/21 9:09 PM, Jaikiran Pai wrote:
> Hello Ioi,
>
>
>>
>> This is my initial analysis of the problem.
>>
>> ====>>> Can anyone think of similar problems that may happen elsewhere?
>>
>> The static constructors of enum classes are executed at both CDS dump
>> time and run time. E.g.,
>>
>> public enum Modifier {
>> OPEN
>> }
>>
>> The <clinit> method essentially does this:
>>
>> public static final Modifier OPEN = new Modifier("OPEN");
>>
>> If a reference of Modifier.OPEN is stored inside the CDS archived
>> heap during dump time, it will be different than the value of
>> Modifier.OPEN that is re-created at runtime by the execution of
>> Modifier.<clinit>
>
> I have almost next to nothing knowledge about CDS internals. My only
> understanding of it is based on some documentation that I have read.
> One of them being this one
> https://docs.oracle.com/en/java/javase/17/vm/class-data-sharing.html#GUID-7EAA3411-8CF0-4D19-BD05-DF5E1780AA91.
>
> Based on that documentation (and other similar ones), it was my
> understanding that CDS was meant to store/share class "metadata" like
> it states in that doc:
>
> "When the JVM starts, the shared archive is memory-mapped to allow
> sharing of read-only JVM metadata for these classes among multiple JVM
> processes."
>
> But from what you explain in that enum example, it looks like it also
> stores class instance data that is computed at build time on the host
> where the JDK image was generated? Did I understand it correctly? Is
> this only for enums or does it also store the static initialization
> data of "class" types too? If it does store the static init data of
> class types too, then wouldn't such data be host/build time specific
> and as such the classes that need to be enrolled into the default CDS
> archive of the JDK should be very selective (by reviewing what they do
> in their static init)? Like I said, I haven't looked into this in
> detail so perhaps it already is selective in the JDK build?
>
Hi Jaikiran,
CDS also has the ability to archive Java heap object. Since
https://bugs.openjdk.java.net/browse/JDK-8244778 , we have archived the
entire module graph to improve start-up time. At run time, the module
graph (as well as other archived heap objects) are loaded from the CDS
archive and put into the Java heap (either through memory mapping or
copying).
You can see the related code in jdk.internal.module.ModuleBootstrap::boot()
When the module system has started up, the module graph will reference a
copy of the OPEN enum object that was created as part of the archive.
However, the Modifier.<clinit> will also be executed at VM start-up,
causing a second copy of the OPEN enum object to be stored into the
static field Modified::OPEN.
When an application tries to get the OPEN enum, it will get the copy
stored in the static field Modified::OPEN. If you walk the module graph,
you get get a reference to the other copy. Since these are two distinct
heap objects, the == operator will return comparing them.
Thanks
- Ioi
More information about the core-libs-dev
mailing list