Java 10 has officially been out for almost a month now, and it brought with it some improvements to the G1 garbage collector. G1 was made the default garbage collector as of Java 9 in favour of Parallel GC, as the general consensus was that low pause times are more important than higher throughput. For more information on how the G1 collector works and how it compares to Parallel GC, check out our blog article here.
There are 2 important JEP’s covering these changes:
JEP 304: Garbage Collector Interface
Introducing an interface for garbage collectors will improve the modularity of the HotSpot JVM, making it much easier and simpler to add a new GC or exclude an existing one from a JDK build.
Before Java10, the garbage collector code was fragmented in places scattered all over the HotSpot sources. This resulted in a few problems:
- Anyone wanting to implement a new GC would require knowledge about all these various places, as well as how to extend the various classes for their specific needs.
- The same knowledge was required to remove / exclude a GC at build time.
- For anyone who wasn’t familiar with the GC code, it was confusing where to find a particular piece of code for a given GC.
As the JEP states: “Adding a new garbage collector should be a matter of implementing a well documented set of interfaces, rather than figuring out all the places in HotSpot that needs changing.”.
The aim is to refactor the HotSpot code so that GC implementations are mostly contained within source files in their respective directories, with as little code as possible outside of them. This code should also be used minimally outside of these directories (any code shared between GC’s should be placed in a helper class), and there should be very few GC specific if-else branches. Finally, as is usually the case, performance should not regress because of any changes made. This should also greatly improve the overall code quality.
While it’s not a goal of this specific JEP to actually add or remove any GC’s, it will definitely help with other JEPs whose goal is to do so, such as 318 – Epsilon: An Arbitrarily Low-Overhead Garbage Collector (which is scheduled for release with Java 11) and 189 – Shenandoah: An Ultra-Low-Pause-Time GC.
JEP 307: Parallel Full GC for G1
The aim of this JEP is pretty much what it says on the tin – to parallelise G1’s full GC algorithm to improve performance.
Although it’s designed specifically to avoid doing full collections, the G1 isn’t perfect in every situation – if it can’t reclaim memory fast enough it’s forced to stop the application threads and clean up. Pre-Java10, a single-threaded mark-sweep-compact algorithm was used for the full GC, so in order to minimise the impact it will now run in parallel on multiple threads (specifically, the same number that the Young and Mixed collections use). Due to the fact that G1 divides the memory up into regions, this change will most likely result in a little more wasted space (compared to a single-threaded algorithm), but in return you get a little boost to throughput and potentially your application’s performance as it’ll be spending less time performing full collections.
You can also customise how many threads are used with the option
-XX:ParallelGCThreads, though keep in mind that this will also affect the number of threads used for the Young and Mixed / minor collections too.
Are there any changes to garbage collection that you’d like to see in a future release of Java? Let us know in the comments below.