JDK-8259798 : Add jcmd option to dump CDS
  • Type: CSR
  • Component: hotspot
  • Sub-Component: runtime
  • Priority: P4
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 17
  • Submitted: 2021-01-14
  • Updated: 2021-11-29
  • Resolved: 2021-02-09
Related Reports
CSR :  
Description
Summary
-------

Supply an option to jcmd to dump shared archive against live java app.

Problem
-------

To dump a static shared archive(CDS archive), user needs first run the java app with flag -XX:DumpLoadedClassList=`<classlist>`, this will write all the shareable java class names into a class list file then exit the app. Second, run with flags -Xshare:dump -XX:SharedArchiveFile=`<static_archive_filename>`  -XX:SharedClassListFile=`<classlist>` to dump CDS archive. The process involves two steps, get class names and dump CDS archive. If user want to dump a dynamic shared archive, they are required to run with -XX:ArchiveClassesAtExit=`<dynamic_archive_filename>`, at java exit, a named archive will be created based on base archive. 

CDS is helping fast startup of java app so first step is the collection of all shareable loaded class names, then run again dump the classes into CDS archive. For current methods to create shared archives, the problems are: 

 1. User could not create CDS in one step.
 2. There may exist some classes which user do not want them included in CDS archive to save space. For example, the classes loaded during shutdown phase.
 3. User may want to dump a CDS archive at any time other than startup and shutdown phases.
 4. Future, we want to store method profiling data into CDS to help JIT start early. User can choose a proper time to dump the CDS when all expected methods already get compiled.
 5. User want to dump a dynamic archive at runtime not at exit.

Solution
--------

Add an option to jcmd named "VM.cds"  with subcommands "static_dump" and "dynamic_dump" to dump static and dynamic CDS archives respectively. The subcommand may take a parameter as shared archive file name.

For static dump, first in current thread which attached to the VM, the loaded shareable class names will be collected and written to a file whose name is based either the given name through command parameter or the process ID. Then, a child process forked to do the dump work, the child process will exit after dumping work done and the parent process keeps running. The static dump can be done multiple times against the live process.

For dynamic dump, the work can be finished in current process, but we need to record some shareable information like class loader constraints at the class loading time. A new flag is introduced, -XX:+RecordDynamicDumpInfo, for this purpose. With the flag the dynamic dumping information needed for a dynamic archive is recorded. Due to a restriction with some object pointer moved around, the dynamic dump can only be done once for the live process.
  

Specification
-------------

A diagnostic command named VM.cds will be added. This command will be the parent command for all commands related to CDS.

The syntax is: 

     jcmd <pid> VM.cds <subcommand> <filename>

- `subcommand` must be `static_dump` or `dynamic_dump`
- `filename` is optional. If omitted, a default file name will be used: `java_pid<number>_static.jsa` for static dump and `java_pid<number>_dynamic.jsa` for dynamic dump, where the `<number>` is the process ID. For given file name, it will end with .jsa if not given 'jsa' as extension.

To use the `dynamic_dump` subcommand, the application must be started with flag `-XX:+RecordDynamicDumpInfo`; this flag cannot be used with `-XX:ArchiveClassesAtExit`.

A class named DumpSharedArchiveDCmd which derives from DCmdWithParser will be added. 

The permission required to start the command will be "java.lang.management.ManagementPermission" "Monitor"

Comments
Moving to Approved.
09-02-2021

This looks good to me, Yumin.
03-02-2021

Thanks Thomas, I have changed the way static dump can work with RecordDynamicInfo on --- you are right. In implementation, I used to copy all the vm args from parent to child, which includes every arg, so if RecordDynamicDumpInfo is set, it also included. The flag will be checked before fork child process and set off if it is on. So this way, both static and dynamic shared archives can be dumped for one live process though the dynamic can only be done once. The file name can be default as `pid<number>_static.jsa` for static and `pid<number>_dynamic.jsa` for dynamic.
02-02-2021

Hi Yumin, Small nit: "User may want to dump a CDS archive at any time when the app is running except for startup and shutdown phases." would maybe clearer as: "User may want to dump a CDS archive at times other than startup and shutdown.". Unless I misunderstand: currently you only either dump at startup (static archive) or shutdown (dynamic archive), right? And the point is to give the user more flexibility and allow dumping at arbitrary points? --- Some questions: - Why not allow for a default file name? - How do I specify which classes to archive for the dynamic case? - Do I understand correctly that I can do only either static or dynamic dump? So if I need both I need to run the VM twice? Since the former needs -RecordDynamicDumpInfo, the latter +RecordDynamicDumpInfo? Why does it matter for the static dump? We fork a new process anyway, could we not just omit RecordDynamicDumpInfo there? Thanks, Thomas
02-02-2021

I like that. Makes sense.
15-01-2021

[~stuefe] Thanks for the suggestion, maybe we can add two options for VM.cds, static_dump and dynamic_dump?
15-01-2021

Just an idea, would an umbrella-command for cds better? In case you want later to add new cds related commands, that would not add another command to the growing list and probably not need a csr. Something like "jcmd VM.cds option" with the sole option now being "dump". Similar to how VM.metaspace works.
15-01-2021