JEP 189: Shenandoah: An Ultra-Low-Pause-Time Garbage Collector

AuthorsChristine H. Flood, Roman Kennke
OwnerRoman Kennke
TypeFeature
ScopeImplementation
StatusCandidate
Componenthotspot / gc
Discussionhotspot dash gc dash dev at openjdk dot java dot net
EffortL
DurationL
Reviewed byAleksey Shipilev
Created2014/01/02 20:00
Updated2018/02/28 17:36
Issue8046179

Summary

Add a new garbage collection (GC) algorithm named Shenandoah which reduces GC pause times by doing evacuation work concurrently with the running Java threads. Pause times with Shenandoah are independent of heap size, meaning you will have the same consistent pause times whether your heap is 200 MB or 200 GB.

Non-Goals

This is not the one GC to rule them all. There are other garbage collection algorithms which prioritize throughput or memory footprint over responsiveness. Shenandoah is an appropriate algorithm for applications which value responsiveness and predictable short pauses. The goal is not to fix all JVM pause issues. Pause times due to reasons other than GC like Time To Safe Point (TTSP) issues or monitor inflation are outside the scope of this JEP. The GC pause time is bounded by the time required to scan all of the thread stacks, this JEP is not making any heroic efforts to place a bound on thread stack scanning time.

Success Metrics

This project will be a success if we can keep consistent short gc pause times regardless of heap size.

Description

Modern machines have more memory and more processors than ever before. Service Level Agreement (SLA) applications guarantee response times of 10-500ms. In order to meet the lower end of that goal we need garbage collection algorithms which are efficient enough to allow programs to run in the available memory, but also optimized to never interrupt the running program for more than a handful of milliseconds. Shenandoah is an open-source low-pause time collector for OpenJDK designed to move us closer to those goals.

Shenandoah trades concurrent cpu cycles and space for pause time improvements. We've added an indirection pointer to every Java object which enables the GC threads to compact the heap while the Java threads are running. Marking and compacting are performed concurrently so we only need to pause the Java threads long enough to scan the thread stacks to find and update the roots of the object graph.

The Shenandoah algorithm is described in depth in this PPPJ2016 paper.

Shenandoah has been implemented and will be supported by Red Hat for aarch64 and for amd64.

The on-going development for Shenandoah is done in the OpenJDK Shenandoah project. See more details on current development flow, implementation details, availability at Shenandoah wiki page.

Alternatives

Zing/Azul has a pauseless collector, however that work has not been contributed to OpenJDK.

ZGC has a low pause collector based on colored pointers. We look forward to comparing the performance of the two strategies.

G1 does some parallel and concurrent work, but it does not do concurrent evacuation.

CMS does concurrent marking, but it performs young generation copying at pause times, and never compacts the old generation. This results in more time spent managing free space in the old generation as well as fragmentation issues.

Testing

Red Hat has done extensive testing for our important applications. We've developed many Shenandoah specific jtreg tests. Shenandoah is shipping in Fedora starting with Fedora 24 and as a tech preview in Rhel 7.4. Running standard OpenJDK testing with -XX:+UseShenandoahGC should be sufficient.

Risks and Assumptions

Once the GC interface (JEP 304) has been integrated the risks of adding Shenanodah to the OpenJDK source base are minimal.