1. Introduction

Java 11 introduced a No-Op Garbage Collector called Epsilon, which promises the lowest GC overhead possible.

In this short tutorial, we’ll explore how Epsilon works, and we’ll mention the common use cases.

2. Quick Hands-On

Let’s start with getting our hands dirty, and take Epsilon GC for a spin!

We’ll first need an application, which creates garbage:

class MemoryPolluter {

    static final int MEGABYTE_IN_BYTES = 1024 * 1024;
    static final int ITERATION_COUNT = 1024 * 10;

    static void main(String[] args) {
        System.out.println("Starting pollution");

        for (int i = 0; i < ITERATION_COUNT; i++) {
            byte[] array = new byte[MEGABYTE_IN_BYTES];
        }

        System.out.println("Terminating");
    }
}

This code creates one-megabyte-arrays in a loop. Since we repeat the loop 10240 times, it means we allocate 10 gigabytes of memory, which is probably higher than the available maximum heap size.

We also provided some helper prints to see when the application terminates.

To enable Epsilon GC, we need to pass the following VM arguments:

-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC

And when we run the application, we get the following error:

Starting pollution
Terminating due to java.lang.OutOfMemoryError: Java heap space

However, when we run the same application with the standard VM options, it completes fine:

Starting pollution
Terminating

Why did the first run fail? It seems like even the most basic garbage collectors could clean up the child’s play that we just demonstrated!

So, let’s take a look at the concepts behind Epsilon GC to understand what just happened.

3. How Epsilon GC Works

Epsilon is a no-op garbage collector.

JEP 318 explains that “**[Epsilon] … handles memory allocation but does not implement any actual memory reclamation mechanism. Once the available Java heap is exhausted, the JVM will shut down.**”

So, this explains why our application terminated with an OutOfMemoryError.

But, it raises the question: Why do we need to have a garbage collector, that doesn’t collect any garbage?

There are some cases when we know that the available heap will be enough, so we don’t want the JVM to use resources to run GC tasks.

Some examples of such cases (also from the related JEP):

  • Performance testing
  • Memory pressure testing
  • VM interface testing
  • Extremely short lived jobs
  • Last-drop latency improvements
  • Last-drop throughput improvements

4. Conclusion

In this short article, we learned about Epsilon, a no-op GC available in Java 11. We learned about the implications of using it and reviewed some cases where it may be handy.

As usual, the examples are available over on GitHub.