Shenandoah – Early findings with running PCGen

 In Garbage Collection, Java

A couple of weeks ago I wrote about the new Shenandoah GC collector from Redhat’s Roman Kenneke and Christine Flood. I managed to grab a quick hour or two today to see if it would just run out of the box against PCGen – a large and complex Swing desktop application that manages characters for role-playing games (yes, yes we are geeks here at jClarity!).

There’s not a huge amount to report on at this initial stage, just some quick observations.


Any observations here should be taken in the context that Shenandoah is very much in the alpha stage. In order to make any serious claims on performance etc should only be done when C2 support comes in.
This post simply captures where it’s currently at from the point of few of a curious developer/ops person with a quick hour to kill.

Shenandoah has yet to provide C2 support

Since Shenandoah is designed to run on large heaps, it lends itself to the types of applications that are considered to be server class. That is, in JVM terms, java is started with -server and uses the C2 compiler.

I only took a handful of wall clock measurements, but screen loading and data processing took anywhere between ~45-55% longer on average. How much of this is C1 vs the GC algorithm used? Not sure and it’s definitely an experiment I need to run.

As an aside, PCGen loads a ton of data through common code paths and tends to benefit from C2’s optimisations, so this slowdown (unscientifically) does make sense.

Shenandoah in its current form crashes on small heaps.

Shenandoah is *not* designed to work on small heaps – it is a solution for large heaps. Unfortunately that translated into an OOME followed by a JVM crash when running PCGen at its default -Xmx512M. If you experience an OOME with Shenandoah you’ll see something like this:

Out of memory. Requested number of words: 6 used heap: 520077448, bytes allocated since last CM: 19443192
ShenandoahHeapRegion: 0x7f8718023eb8/0 live = 4576152 garbage = 3812432 claimed = 0 bottom = 0x7f86f0000000 end = 0x7f86f0800000 top = 0x7f86f07fffe8 active_tlabs: 0

Snip lots of similar ShenandoahHeapRegion: logging output

ShenandoahHeapRegion: 0x7f86b4259ca8/62 live = 0 garbage = 0 claimed = 0 bottom = 0x7f870f000000 end = 0x7f870f800000 top = 0x7f870f000000 active_tlabs: 0
Printing 46 free regions:
ShenandoahHeapRegion: 0x7f8718025b38/24 live = 2372960 garbage = 6015624 claimed = 0 bottom = 0x7f86fc000000 end = 0x7f86fc800000 top = 0x7f86fc7fffe8 active_tlabs: 0

Snip lots of similar ShenandoahHeapRegion: logging output

ShenandoahHeapRegion: 0x7f86b42513d8/61 live = 8388584 garbage = 0 claimed = 0 bottom = 0x7f870e800000 end = 0x7f870f000000 top = 0x7f870effffe8 active_tlabs: 0
ShenandoahHeapRegion: 0x7f86b4259ca8/62 live = 0 garbage = 0 claimed = 0 bottom = 0x7f870f000000 end = 0x7f870f800000 top = 0x7f870f000000 active_tlabs: 0
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc: SuppressErrorAt=/shenandoahHeap.cpp:578
# A fatal error has been detected by the Java Runtime Environment:
# Internal Error (/home/karianna/workspace/shenandoah/hotspot/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp:578), pid=20162, tid=140216959141632
# assert(false) failed: Out of memory
# JRE version: OpenJDK Runtime Environment (8.0) (build 1.8.0-internal-debug-karianna_2014_03_04_15_29-b00)
# Java VM: OpenJDK 64-Bit Client VM (25.0-b67-debug mixed mode linux-amd64 )
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
# An error report file with more information is saved as:
# /home/karianna/workspace/pcgen/pcgen/hs_err_pid20162.log
# If you would like to submit a bug report, please visit:
Current thread is 140216959141632
Dumping core ...
Aborted (core dumped)

Shenandoah in its current form appears stable on larger heaps.

When running PCGen with -Xmx1024M it ran stably with no crashes during a variety of use cases invoking I/O from disk, network I/O, XML transformations, Swing Desktop code and use of j.u.concurrent package constructs.

System.gc() & Shenandoah?

An attempt to call System.gc() effectively failed (no heap was reported recovered via the JMX interface) but it didn’t crash the JVM either. This was pretty much expected as I doubt Shenandoah has support for System.gc() wired in yet (and perhaps it shouldn’t!).

It’s worth noting that the numbers coming out of the JMX bean could be completely false, I didn’t take a look at the source code to see if numbers are wired up correctly.

Is it worth experimenting with yet?

If you’re a curious developer/end-user then probably not. Shenandoah needs to provide C2 support and some stability around low heap sizes before people can start to compare sensibly against G1 or other collectors.

Even for performance tuning experts with benchmarking experience, there’s not enough Apples vs Apples support to attempt any serious benchmarking.

Is it worth working on?

Absolutely! We encourage people who want to learn about the inner workings of a working GC and/or otherwise get involved to take a look at Roman’s latest blog post which details all of the resources for the project to date.

Martijn (CEO) and the jClarity Team!

No more memory leaks and application pauses!

Find out why my app is slow and tell me how to fix it!

Recent Posts