Last week I got the chance to attend JAX London for a brilliant two-day conference. While several of the presentations and keynotes were interesting the one that really stuck with me afterwards was a small and relatively under-attended talk about the Java G1GC garbage collector by Monica Beckwith.
I get it — garbage collection isn’t the most thrilling of subjects for most of us, and, frankly, most of the time it is one of those things you are only vaguely aware is taking place. After this session though, I’ve been thinking quite a lot about garbage collection and the impact a well configured GC can have on performance. Given how much time is spent on optimising performance in a lot of applications and how much time we spend performance-testing, it seems rather strange that we are often happy to just let our GC be, with only a minimum, if any, changes to its default configuration.
In my own experience, something as simple as switching from one GC to another can drastically alter performance and stability. Performance and integration tests that previously were flaky or outright destructively unstable can be made reliable enough to run smoothly on every build job. If a good performance or efficiency gain can be made by simply setting a flag to change our GC, then it stands to reason that tweaking our garbage collectors further for specific applications could also be beneficial.
For example, when was the last time we configured our ‘heap occupancy percentage’, which represents the threshold that triggers the collector’s marking cycle?
G1GC offers plenty of configurable options we can set:
- G1HeapRegionSize
- MaxGCPauseMillis
- G1NewSizePercent
- G1MaxNewSizePercent
- ParallelGCThreads
- ConcGCThreads
- InitiatingHeapOccupancyPercent
- G1HeapWastePercent
- G1MixedGCCountTarget
- G1OldCSetRegionThresholdPercent
- G1ReservePercent
All of these have default values. Do you know them? Honestly, I don’t.
Oracle provides an excellent article on configuring G1GC, which can be found here.
In the end, tweaking the garbage collector does sound like one of those things that you just have to get through, rather than looking forward to doing. I do, however, think it is only fair, and probably smart, to start considering garbage collection and the impact it can have on our applications beyond simply leaving the default be, as “good enough”.