Open J9’s Balanced GC policy is a region based, incremental generational collector, unlike the default generational concurrent policy (gencon), which is probably best suited for the most traditional java application, Balanced GC is designed to be used on large heap to reduce maximum pause times.
In Balanced GC The Java heap is divided into a large number of fixed size regions (1,024 – 2,047) and regions grouped into max 24 generations, new objects are only allocated in eden regions (region age 0).
Two major GC cycles (Partial Garbage Collection (PGC) and Global Mark Phase (GMP)) are used to reclaim memory in Balanced GC, in general PGCs are the most common GC cycles, and occasionally GMP cycle kick off, overlap and interleave with a few PGC cycles.
Partial Garbage Collection (PGC) is Stop-The World (STW) GC cycle, it collects a subset of regions (the collection set), which includes eden regions, highly fragmented regions and, regions with a high mortality rate. Two algorithms are used in PGC cycle: Copy Forward and Mark & Compact.
Copy Forward is copy collector, similar scavenge in GenCon policy, require only 1-pass scanning and copying and good locality of objects in survivor area, but it need to consumes a subset of free regions in the heap to copy all live objects of the collection set.
In other hand, Mark & Compact, as equivalent of Global collection in Gencon (just on region level), does not require any free memory and it is slightly faster than copying collector if it is without compactor, but mark and compact will together do two passes through the live objects, it could cause longer collection pause.
So the collection pause time for Mark & Compact is typically 50%-100% longer than Copy Forward’s. Copy Forward is the default algorithm for PGC, Mark & Compact is alternative approach in case Copy Forward can not be run.
JNI Critical region
JNI Critical (within pairs of GetXXXCritical and ReleaseXXXCritical) is used when a native method needs to obtain direct addressability to the inside of Java objects, While any Java thread is in such a critical section, JVM need to maintain that the pinned “critical object” is not moved. The region containing “critical object” is called “critical region” (There is no individual “critical object” protection from to be moved but limitation for entire region content to be moved).
It is one of major reason that PGC cycle pick Mark & Compact for the collection due to Copy Forward can not be used if there is JNI critical region in collection set (eden regions).
Base on the result of SPECjbb® 2015 composite mode testing in Balanced GC, there are more than 50% Mark & compact PGCs are caused by JNI Critical section, but for the most cases the “critical objects” only in one or a few regions.
Copyforward&Mark Hybrid Collector
Mark & Compact was used in PGC cycle in the case if even single “critical object” exists in the heap, if we can mark & sliding compact the “critical regions” and apply copy forward for the rest of collection set, then we can reduce the PGC pause time.
The new Copyforward&Mark Hybrid Collector intent to avoid to mark compact whole the collection set for JNI Critical case.
the new collector can run both copy forward algorithm and mark compact algorithm simultaneously,
- In pre-collection stage, set a “pinned” mark for any non-moving regions in collection set.
- The tracing work is normally driven by copy-scan cache for copy forward and driven by marking work stack for marking compact, in hybrid collector copy phase and mark phase have been merged together (copy and mark phase). In copy and mark phase, synchronize all collection threads with both copy-scan caches (for copying) and marking work stack (for marking) and the tracing work can be pulled from either of them. The priority of retrieving tracing work can be defined as copy-first, also in runtime the priority can be changed to mark-first depends on marking work stack availability threshold to avoid marking work stack overflow case.
- If live Object is in the pinned region, mark it and push the reference into marking work stack, otherwise copy it to copy-scan cache in survivor.
- The tracing work complete when both copy-scan cache and marking work stack are empty. After completing tracing work, sweeping apply to pinned regions.
- There are two exception handling cases
- When copying operation aborts due to insufficient memory space, stop to pull new tracing works from marking work stack and follow copying collector abort process.
- If marking work stack overflow is detected after completing tracing work, set abort flag and follow copying collector abort process (abort process has already handle the marking work stack overflow case).
Replacing Copy Forward and PGC Mark
Copyforward&Mark Hybrid can handle copy or mark on any arbitrary regions in collection set, if there are no pinned regions, it would run full copy forward mode without performance impact, if all of regions are pinned, it would act as mark compact with minor performance difference.
So we update Copy Forward algorithm to Copyforward&Mark Hybrid and also remove PGC Mark-only algorithm.
New testing option -XXgc:fvtest_forceCopyForwardHybridMarkCompactRatio=x (0<= x <=100, x is the percentage of collection set to be reserved for mark compact) is also added for margin testing (-XXgc:fvtest_forceCopyForwardHybridMarkCompactRatio=100 will force PGC running under MarkCompactOnly mode).
Verbose gc also is updated to match new Copyforward&Mark Hybrid. The new tag <regions> has been added for identifying the mode of Copyforward&Mark Hybrid collector.
In Figure 4, the PGC cycle shows the collector is running under Full Copyforward mode (all of regions are copied, there is only eden and non eden region count for the collection set in <regions> tag).
In Figure 5, the PGC cycle shows the collector is running under hybrid mode (only one region is marked/compacted-‘marked’, the rest of regions are copied-‘evacuated’). Tag <memory-traced> also shows how many live objects are marked.
In Figure 6, the PGC cycle shows the collector is running under Mark Compact mode (none of regions are copied due to no free memory is available at the beginning of the collection).
Copyforward&Mark Hybrid collector is garbage collection algorithm optimization for reducing pause time regressions in the presence of JNI critical regions during garbage collection, it also simplify balanced Partial Garbage Collection cycle to remove some limitations for implementing concurrent PGC in future.