Maksim Kabakou - Fotolia
You can't force garbage collection in Java. There are some strategies you can use to get the Java virtual machine to prioritize the task, but the indeterminate nature of garbage collection means the process can't be forced.
Similarly, you can't stop Java garbage collection from happening, either. You can change some configuration settings in the Java virtual machine (JVM) that impact the variables that trigger garbage collection (GC) routines, but you can't completely stop Java GC from happening. Or can you?
Epsilon GC, also known as Java's no-op garbage collector, provides memory allocation facilities but it doesn't do any memory reclamation. Epsilon GC doesn't just prevent Java garbage collection from happening -- it eliminates GC altogether.
Epsilon GC is an experimental feature released with JDK 11. To start an application or microservice on a JVM with Epsilon GC enabled, include the following JVM options:
Pros and cons of Epsilon GC
So, what's so great about Epsilon GC? DevOps professionals who deploy applications and microservices to JVM with it get the lowest memory management latency.
The drawback? When the JVM reaches the limits of its allocated memory, it will crash and burn with an OutOfMemoryError, terminating the JVM. Once the Java heap is exhausted, no further object allocations are possible. And since no memory reclamation is allowed, the JVM will fail with an OutOfMemoryError written to the logs and a heap dump written to the file system.
When to use Epsilon GC
Why would anyone want to use a Java memory management tool whose normal operation has the potential to terminate the JVM? There are a few valid use cases for Epsilon GC, including:
- performance testing routines where GC routines skew the gathered metrics;
- extremely short-lived routines where the JVM is terminated on exit;
- for ultra-latency sensitive applications where the memory footprint is well-established;
- for garbage-free applications that perform primarily iterative and conditional logic;
- for highly clustered Java-based microservice deployments on Kubernetes where intermittent JVM failures are unlikely to cause a service degradation; and
- for servers that allocate immense quantities of memory at startup and then cycle down at the end of the workday.
A common use case for Epsilon GC is the determination of optimal memory management settings for the JVM. To determine the best Java heap size settings for an application, an application can be tested under load with the no-op garbage collector turned on. Profiling tools like Java Flight Recorder and JDK Mission Control can then be used to determine optimal Xms and Xmx settings for the minimum and maximum heap sizes. This approach generates performance metrics that are untainted with the additional overhead required to perform memory reclamations.
When developers and DevOps professionals inquire about the ability to stop the JVM, they typically want to delay it for 10 or 15 minutes so they can avoid a stop-the-world event during critical service windows. Unfortunately, there is no such command, API or JDK utility that will temporarily pause Java GC.
The closest option available is to take advantage of Epsilon GC, JEP-318, and turn off GC completely. Then, build a Java memory management strategy that builds around the inevitable heap dump and OutOfMemoryError that will occur if object creations exceed the amount of memory allocated to the heap.