Proposal for improving CDS archive creation
Ioi Lam
ioi.lam at oracle.com
Tue Jul 10 17:16:10 UTC 2018
I have a proposal for improving the process of creating of the CDS
archive(s),
so we can make CDS easier to use and support more use cases.
- better support for custom loaders
- remove explicit training run
- support 2 levels of shared archives
I think the proposal is relatively straight-forward to implement, as we
already
have most of the required infrastructures:
+ the ability to use Java class loaders at archive creation time
+ the ability to relocate MetaspaceObjects
Parts of this proposal will also simplify the CDS code and make it more
maintainable.
Current process of creating the base archive - [C]
==================================================
Currently each JVM process can map at most one CDS archive. Let's call this
the "base archive". It is created by [ref1]:
C1. Reserve a region R of 3GB at 0x800000000.
C2. Load all classes specified in the class list. All data for these
classes
live outside of R.
(E.g., the Klass objects are loaded into tmp_class_space, which is
adjacent to R).
C3. Copy the metadata of all archivable classes (e.g, exclude generated
Lambda classes) into R. At this step, R is divided into several
sections (RO, RW, etc).
// +-- SharedBaseAddress (default = 0x800000000)
// +-- _narrow_klass._base
// |
// | +-tmp_class_space.base
// v V
// +----+----+----+----+----+-....-+-------------------+
// |<- R ->|
// | MC | RW | RO | MD | OD |unused| tmp_class_space |
// +----+----+----+----+----+------+-------------------+
// |<-- 3GB -------------->|
// |<-- UnscaledClassSpaceMax = 4GB ------------------>|
New process for creating the base archive - [N]
===============================================
Currently we have a lot of "if (DumpSharedSpaces)" code to for special case
handling of the above scheme. We can improve it by
N1. Remove all code for special memory layout initialization for
-Xshare:dump.
As a result, we will reserve a region R of 1GB at 0x800000000, which
is used by Klass objects (this is the same as if -Xshare:off were
specified.)
N2. Load all classes in the class list.
N3. Now R contains the Klass objects of all loaded classes.
Allocate a temporary space T, and copy all contents of R into T.
N4. Now R is empty. Copy the metadata of all archivable classes into R.
Dump-as-you-go for the base archive - [G]
=========================================
Note that the [N] scheme will work even if you're running an app with
-Xshare:off. At some point (e.g., when the VM is about to exit), you
can:
G1. Enter a safe point
G2. Go to step [N3].
The benefit of [G] is you don't need a separate run to dump the archive, and
there's no need to use the class list. Instead, we can have an option like:
java -Xshare:autocreate -cp app.jar -XX:SharedArchiveFile=foo.jsa App
If foo.jsa is not available, we run in [G] mode. At VM exit, we dump into
foo.jsa.
This way, we don't need to have an explicit training run with
-XX:DumpLoadedClassList. Instead, the training run is
This also makes it easy to support the classes from custom loaders.
There's no
need for special tooling to convert -Xlog:class+load=debug output into a
classlist. [ref2]
Dumping for second-level archive - [S]
======================================
S1. Load the base archive
S2. Run the app as normal
S3. All Klass objects of the dynamically loaded classes will be loaded in
the region R, which immediately follows the end of the base archive.
// +-- SharedBaseAddress
// | +--- dynamically loaded Klasses
// | | start from here.
// v v
// +--------------------------+---------...-----------------|
// | base archive | region R |
// +--------------------------+---------...-----------------|
// |<- size of base archive ->|
// |<-- 1GB -->|
S4. At some point (possible when the VM is about to exit) we start
dumping the second level archive
S5. Enter safe point
S6. Now R contains the Klass objects of all dynamically loaded classes.
Allocate a temporary space T, and copy all contents of R into T.
S7. Now R is empty. Copy the metadata of all archivable, dynamically
loaded
classes into R.
S8. Create a new shared_dictionary (and shared_symbol_table) that
contains
all the Klasses (Symbols) from both the base and second-level
archives.
References
==========
[ref1] Current initialization of memory space layout during -Xshare:dump
http://hg.openjdk.java.net/jdk/jdk/file/e0028bb6dd3d/src/hotspot/share/memory/metaspaceShared.cpp#l250
[ref2] Volker Simonis's tool for support custom class loaders in CDS
https://github.com/simonis/cl4cds
----------------------------------------------------------------------
Any thoughts?
Thanks
- Ioi
More information about the hotspot-runtime-dev
mailing list