Key

This line was added.

This line was removed.

Formatting was changed.

Welcome to the Shenandoah Project!

Shenandoah is an ultra-low pause time garbage collector that reduces GC pause times by performing more garbage collection work concurrently with the running Java program. CMS and G1 both perform concurrent marking of live objects. Shenandoah adds concurrent compaction.

Build and Run

Shenandoah is under development. There are several ways to try it:

Build the bleeding edge from the JDK 9 source. This would guarantee you run the latest and greatest version. Adding --enable-debug to configure would produce the "fastdebug" build.

Build the JDK 8 backport: same as above, but change "jdk9" to "jdk8u" in the paths above. The advantage is that you don't need to figure out JDK 9 compatibility issues for your application first (although it is a good idea to try JDK 9 now anyway). The downside is, that forest may easily be several months behind the JDK 9 version. If you encounter trouble with JDK 8 version, please try JDK 9 version.

Many odd performance potholes are solved by giving the collector enough heap. Try to see how GC performs on different heap sizes.

-Xlog:gc=info would print the individual GC timings. This is not specific to Shenandoah, most recent GCs with JDK 9 Unified Logging would work like that.

-Xlog:gc+stats would print the summary table on Shenandoah internal timings at the end of the run.

If you suspect a GC bug, it is a very good idea to run with "fastdebug" builds. These can be produced by adding --enable-debug to configure, and building. Shenandoah asserts a lot of things, and it usually reveals a lot about the issue.

If you suspect a JIT bug (and there are lots of Shenandoah-specific optimizations), it is a very good idea to try bisect which compiler failed by trying several VM modes: -Xint (interpreter only), -XX:TieredStopAtLevel=1 (C1 only), -XX:-TieredCompilation (interpreter and C2 only), default (interpreter, tiered C1, tiered C2).

If you suspect a bug in concurrent phases, read/write barriers, etc., try running with -XX:ShenandoahGCHeuristics=passive, which will do the stop-the-world mark-compact GCs only, and avoid doing most of concurrent work.

GC bugs can be shaken out more quickly with -XX:ShenandoahGCHeuristics=aggressive, which runs back-to-back GCs. Since Shenandoah does most GC heavy-lifting concurrently, this does not block application from executing, although GC would consume much more cycles in this mode and slow the application down.