Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

authorAuthor: Jiangli Zhou (jiangli)Thomas Schatzl (tschatzl)

...


This page gives some details how the Hotspot VM maintains archived (cached) Java heap objects.

Supported Platforms and Configurations

  • Supports 64-bit, non-Windows platforms only.

  • Supports G1 GC only.

  • Requires UseCompressedOops and UseCompressedClassPointers set.

Types of Pinned G1 Heap Regions

...

  • 00100 0 [ 8] Pinned Mask 
  • 01000 0 [16] Old Mask
  • 10000 0 [32] Archive Mask 
  • 11100 0 [56] Open Archive:  ArchiveMask | PinnedMask | OldMask
  • 11100 1 [57] Archive           : ArchiveMask | PinnedMask | OldMask + 1

Pinned Regions

Objects within the region are 'pinned', which means GC does not move any live objects. GC scans and marks objects in the pinned region as normal, but skips forwarding live objects. Pointers in live objects are updated. Dead objects (unreachable) can be collected and freed.

...

The archive-types are sub-types of 'pinned'. There are two types of archive region currently, open archive and closed archive. Both can support caching java Java heap objects via the CDS (Class Data Sharing) archive.

An archive region is also an old region by design.

Open Archive (GC-RW) Regions

...

Open archive region does not have 'dead' objects. Unreachable objects are 'dormant' objects. Dormant objects are not collected and freed by GC. Please see Dormant Objects for details.

Caching java Java objects with open archive region may help JVM startup and runtime performance.

Open Archive Heap Region Verification

All live objects and dormant objects are verified to make sure they only point to live objects or archived objects.

Adjustable Outgoing Pointers

As GC can adjust pointers within the live objects in open archive heap region, objects can have outgoing pointers to another java Java heap region, including closed archive region, open archive region, pinned (or humongous) region, and normal generational region (young, old). When a referenced object is moved by GC, the pointer within the open archive region is updated accordingly.

...

The closed archive region is GC read-only region. GC cannot write into the region. Objects are not scanned and marked by GC. Objects are pinned and not forwarded. Pointers are not updated by GC either. Hence, objects within the archive region cannot have any outgoing pointers to another java Java heap region. Objects however can still have pointers to other objects within the closed archive regions (we might allow pointers to open archive regions in the future). That restricts the type of java Java objects that can be supported by the archive region.

Supported java Java objects:

  • Primitive arrays (not changed at runtime once initialized)
  • String and the underlying 'value' array
  • Closed and runtime 'immutable' object graph
    • Not changed at runtime once initialized
    • No out-going references to non-closed archive GC regions

In JDK 9 we added the support archive for shared Strings with the (closed) archive regions.

The GC-readonly archive region makes java Java heap memory sharable among different JVM processes.

NOTE: synchronization on the objects within the archive heap region can still cause writes to the memory page.

Closed Archive Regions Verification

Objects can only point to objects within the closed Archive region.

Dormant Java Objects

Dormant Java objects are unreachable java Java objects within residing in the open archive heap region(s)

A java Java object in the open archive heap region is a live object if it can be reached during scanning. Some of the java Java objects in the open region may not be reachable during scanning. Those objects are considered as dormant, but not dead. For example, a constant pool 'resolved_references' array is reachable via the klass root only if its container klass (shared) is already loaded at the time during the current GC scanning. If a shared klass is not yet loaded, the klass root is not scanned and it's constant pool 'resolved_reference' array (A) in the open archive region is not reachable. Then A is a dormant object.

Object State Transition

All java Java objects are initially dormant objects when open archive heap regions are mapped to the runtime java Java heap. A dormant object becomes live object when the associated shared class is loaded at runtime. Explicit call to G1SATBCardTableModRefBS::enqueue() needs to be made when a dormant object becomes live. That should be the case for cached objects with strong roots as well, since strong roots are only scanned at the start of GC marking (the initial marking) but not during Remarking/Final marking. If a cached object becomes live during concurrent marking phase, G1 may not find it and mark it live unless a call to G1SATBCardTableModRefBS::enqueue() is made for the object.

Currently, a live object in the open archive heap region cannot become dormant again. This restriction simplifies GC requirement and guarantees all outgoing pointers are updated by GC correctly. 

Currently, only Only objects for shared classes from the builtin class loaders (the boot loader, PlatformClassLoaders, and AppClassLoaders) are supported for caching currently.

New/Updated GC APIs

G1ArchiveAllocator

...

In Closed Archive Heap Region

  • Interned

...

  • Java.lang.String objects and the underlying 'value' objects
  • Primitive box caches and the cached objects (JDK-8209120JDK-8213033)

In Open Archive Heap Region

  • Class mirror objects (

...

  • Java.lang.Class objects)
  • Class constant pool resolved_references arrays
  • Module Graph (Sub-graph of Java Heap Objects)
  • System Module Boot layer Configuration (JDK-8207263

...

  • )

Caching Java Objects at Archive Dump Time

The closed archive and open archive regions are allocated at the top (or near the top) of the dump time java Java heap. Archived java Java objects are copied into the designated archive heap regions. For example, String objects and the underlying 'value' arrays are copied into the closed archive regions. All references to the archived objects (from shared class metadata, string table, etc) are set to the new heap locations. A hash table is used to keep track of all archived java Java objects during the copying process to make sure java Java object is not archived more than once if reached from different roots. It also makes sure references to the same archived object are updated using the same new address location.

...

At runtime as part of ConstantPool::restore_unshareable_info() work, call G1SATBCardTableModRefBS::enqueue() to let GC know the 'resolved_references' is becoming live. A handle is created for the cached object and added to the loader_data's handles.

Class Redefinition Interaction

No issue.

When a shared class is redefined at runtime, the 'resolved_references' array is reallocated for the 'scratch_class'. The cached array will not be in use.

VM_RedefineClasses::load_new_class_versions()
  ->Rewriter::rewrite()
    ->Rewriter::Rewriter()
      ->Rewriter::make_constant_pool_cache()
        -> initialize_resolved_references()

The cached array object is reachable from the handle in ClassLoaderData (_ handles). For shared classes from the three builtin loaders (boot, PlatformClassLoader and AppClassLoader), the cached 'resolved_references' array is still kept alive after redefinition.

Runtime Java Heap With Cached Java Objects

The closed archive regions (the string regions) and open archive regions are mapped to the runtime java Java heap at the same offsets as the dump time offsets from the runtime java Java heap base. 

Archive Heap Region Verification

Open Archive Regions

All live objects and dormant objects are verified to make sure they only point to live objects or archived objects.

Closed Archive Regions

Objects can only point to objects within the closed Archive region.