JDK-8275142 : Configurable card table card size
  • Type: CSR
  • Component: hotspot
  • Sub-Component: gc
  • Priority: P4
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 18
  • Submitted: 2021-10-12
  • Updated: 2021-11-29
  • Resolved: 2021-11-29
Related Reports
CSR :  
Description
 Summary
-------

Introduce the product command line option `GCCardSizeInBytes` to set the range of memory covered by a card.

Problem
-------

In an incremental garbage collector, if you evacuate an object during garbage collection, i.e. move it, any other references to that object must be adjusted to the new object location. It is essential for performance to find these references from non-evacuated areas quickly.

In Serial, Parallel and G1 GC the card table helps finding these references: the elements of this array, the cards, subdivide the Java heap into small (few hundred bytes) disjunct areas that during garbage collection store information whether that small area potentially contains such a reference. Such a card potentially containing a reference is considered "dirty" (as opposed to "clean").

During garbage collection, instead of looking through references of all objects of the heap for references into memory that is evacuated, only look for references in the area represented by dirty cards. Since this area is magnitudes smaller than the entirety of non-evacuated Java heap areas, this mechanism is much faster.

The size of the area a card table entry covers ("card size" in the following) is a trade-off between performance and memory usage - larger cards use less memory for the card table array, but require more work during the garbage collection pause to find the sought after references.

Currently card size is fixed at compile time to 512 bytes. It is unknown how that value has been determined; literature suggests that values down to 128 bytes were in use. For an upper limit, current implementation allows up to 1024 bytes for card size.

Internal tests showed reductions in pause time of up to 30% when using a card size of 256 or 1024 bytes depending on the application.

Solution
--------

Allow the user set the card size at VM startup within 128 and 1024 bytes.

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

    --- a/src/hotspot/share/gc/shared/gc_globals.hpp
    +++ b/src/hotspot/share/gc/shared/gc_globals.hpp @@ -692,9 +692,13 @@
       product(uintx, GCDrainStackTargetSize, 64, \
               "Number of entries we will try to leave on the stack " \
               "during parallel gc") \
    - range(0, max_juint)
    -
    -// end of GC_FLAGS
    + range(0, max_juint) \
    + \
    + product(uint, GCCardSizeInBytes, 512, \
    + "Card table entry size (in bytes) for card based collectors") \
    + range(128, 1024) \
    + constraint(GCCardSizeInBytesConstraintFunc,AtParse)
    + // end of GC_FLAGS 
Comments
Moving back to Approved.
29-11-2021

The change did not work for 32 bit machines, the upper bound described here can not be supported. Here's that CSR: https://bugs.openjdk.java.net/browse/JDK-8277891
29-11-2021

Changed back this CSR to the original text after the discussion with the CSR team. Going to file a new CSR for the 32 bit change. Still needs re-approval. Sorry for the confusion.
29-11-2021

Asking for re-approval because the suggested upper limit of 1024 bytes does not work for 32 bit platforms (see JDK-8277854). Since this is a new flag introduced in JDK 18, there are no further compatibility issues.
26-11-2021

Moving to Approved.
19-11-2021