Disable Java Garbage Collection? | Epsilon GC

Reading Time: 6 minutes

Java garbage collection is one of the perks of being a Java developer. Always enabled and working for us in the background. However there are some interesting cases where you want to disable Java garbage collection! Get introduced to the Epsilon no-op garbage collector.

Epsilon nop-op Garbage Collector | What is it?

Java 11 introduced an experimental GC called the Epsilon no-op GC. There are many different GC’s to chose from but Epsilon is the most different for sure. Epsilon is the lowest overhead Java GC available. This means it doesn’t degrade performance by introducing random GC pauses while our application is executing. Basically it’s a GC that does no actual garbage collection … weird, huh?

Epsilon however continues to allocate memory until there is no room left on the heap. At that point, the JVM shuts down due to out of memory errors. You enable it via the java command option –XX:+UseEpsilonGC

Where to Disable Java Garbage Collection?

It’s definitely not meant for production but it can be great to use in a testing environment. Of course, I’m not suggesting to use it for all your tests because that would not be practical. You would eventually run out of memory for the wrong reasons.

What I am suggesting is that there are some specific types of tests which can benefit from the absence of the garbage collection process.

When running tests, It can be frustrating when you’re trying to benchmark application performance under some purposely induced stress/load. These tests are executed over a short run and your results may be off due to one or more GC cycles kicking in during your test. The after math may show that a lot of time and resources were spent on the garbage collection process.

What to do then when you don’t want GC to stop you in the middle of a stress test? This and some other test use cases are where we can improve Java testing efficiency by disabling the Java GC.

When to Disable Java Garbage Collection?

Here are some testing scenarios when it could be advantageous to disable Java garbage collection.

  • Performance testing and micro bench-marking algorithms
  • Running regression tests to identity memory leaks
  • Testing third party libraries, Java API’s and your own as well for memory allocations under usage.
  • Simulating OOM errors in a microservices architecture where containers just die. Does the cluster recover as expected on an application level and orchestration level?

By turning off Java GC for these test cases, we would be able to get accurate results and side step unpredictable pauses.

Java Epsilon no-op GC in Action

The following example simulates a load test by creating many new byte[] Objects until an entire GigaByte’s worth is populated into the ArrayList.

Once the above code is packaged into a jar file, we can execute the jar command from the CLI with garbage collection logs enabled to see what is going on. I am capping the minimum and maximum Java heap space size to 1 GigaByte on the CLI.

As expected, Java 11’s G1 GC is trying to do its best to keep up with the fury of objects being carelessly created. However it eventually dies with a OutOfMemoryError as seen on the last line.

Let’s take a look with the the Epsilon no-op GC. Since this is an experimental feature, we also need to include the -XX:+UnlockExperimentalVMOptions in the follow java command.

 

The above test ran without any garbage collection interruptions until the OOM Exception  occurs. This made the code run much faster as well as utilize less CPU resources. With this predictable behavior, you’re now free to tackle the testing use cases mentioned above.

Lazy isn’t always bad after all, thanks Epsilon!