How to get by without Concurrent Mark Sweep
As part of JEP-291, the popular Concurrent Mark Sweep garbage collection algorithm has been deprecated by Java Development Kit 9. This decision was made to both reduce the maintenance burden of garbage collection (GC) code and to accelerate new development.
As a result, if you launch an application from Java 9 or later with the -XX:+UseConcMarkSweepGC argument to activate the Concurrent Mark Sweep GC algorithm, you will see the following warning:
Java HotSpot(TM) 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release.
Why was Concurrent Mark Sweep deprecated?
If there’s a lot of baggage to carry, especially in Java code, it’s hard to move forward. With Concurrent Mark Sweep, this feature is exactly what led to its demise. It is a highly configurable, sophisticated algorithm and adds a lot of complexities to the GC code base in the Java Development Kit (JDK). However, it’s only when a JDK development team can simplify the GC code base, can it accelerate and innovate in the GC arena.
Let’s explore the number of Java Virtual Machine (JVM) arguments that can be passed to each GC algorithm to to demonstrate how complex they are:
- Common to all: 50
- Parallel: 6
- CMS: 72
- G1: 26
- ZGC: 8
There are around 50 GC-related arguments that can be passed to any JVM. On top of these 50 arguments, CMS alone can pass 72 additional arguments, which is a significantly greater number than any other GC algorithms. This increase adds significant coding complexity for a JDK team to support all these arguments.
If you currently use CMS as your GC algorithm, what are your options?
The three most compelling options are:
- Switch to the G1 GC algorithm
- Switch to the Z GC algorithm (Early access in JDK 11, 12)
- Continue with CMS, and deal with the deprecation warnings
Switch to G1 GC algorithm
G1 GC has become the default GC algorithm since Java 9, and you may safely consider an application move to this algorithm. It could provide better performance characteristics compared to Concurrent Mark Sweep, and it’s much easier to tune this algorithm because it contains a smaller number of arguments. Also, it provides options to eliminate duplicate strings from memory. If you can eliminate these duplicate strings, it can help you reduce the overall memory footprint.
Switch to Z GC algorithm
Z GC is a scalable, low-latency garbage collector with a main goal to keep GC pause times less than 10 ms. Early access of the Z GC algorithm is available in Java 11 and 12, so if your application runs on one of those releases, you can consider this as a Concurrent Mark Sweep alternative.
Continue with Concurrent Mark Sweep
For certain applications, Concurrent Mark Sweet delivers better results compared to the G1 GC algorithm, even with a lot of tuning. If you’ve explored the alternatives and seen that Concurrent Mark Sweep provides the best result for your applications, you should just stick with your current GC algorithm.
There have been discussions about keeping Concurrent Mark Sweep alive in the OpenJDK JDK9-dev mailing list, so it may not be gone forever. Certain features and APIs that were deprecated 20 years ago in Java 1.1 are still used in modern day applications, which means that deprecation isn’t always the end of the road. You can continue to run on Concurrent Mark Sweep, but be aware that it may be removed completely in any future release.
Note that each application is unique and different, and don’t get carried away by journals and other literature that talk about GC tuning and tweaking. When you instrument a new GC setting, you should complete thorough testing, denote benchmark performance characteristics and study key performance indicators to make an informed decision.