As heap utilization approaches 100% and the inevitable OutOfMemoryError threatens to crash the production JVM, DevOps professionals who tend real-time Java applications are wont to ask for a mechanism to force Java garbage collection and free up a few megabytes in memory.
Unfortunately, this desire to immediately free up memory must go unrequited, as there is no way to force garbage collection (GC) in Java. However, here are five strategies that will get the Java Virtual Machine (JVM) to prioritize the task.
1. Call System.gc()
Developers can call System.gc() anywhere in their code to instruct the JVM to prioritize garbage collection. When a developer calls this method -- and there isn't an extreme load on the JVM -- a Java GC cycle will happen within seconds.
2. Call Runtime.getRuntime().gc()
Another option is to use the Runtime.getRuntime().gc() call. This is the second function the JDK provides for developers who want to force Java garbage collection. The Runtime.getRuntime().gc() call actually just invokes the method System.gc() behind the scenes. As a result, the two method calls are exactly the same.
3. Use jmap to force GC
The Java Memory Map (JMAP) utility has a method that prints a histogram of the Java heap. One side effect of the jmap command is that when it's called, it forces a garbage collection routine. However, this isn't a foolproof way to force Java garbage collection. If the JVM is busy and a GC cycle cannot be performed, the command will error out.
$ jmap -histo:live 7544
4. Command line Java GC with jcmd
The Java diagnostic command (JCMD) is another JDK utility that will trigger a garbage collection routine if the JVM can safely schedule a stop-the-world pause. If not, this command will error out in the same manner as the jmap utility.
$ jcmd 7544 GC.run
5. Use JConsole or Java Mission Control
Both JConsole and Java Mission Control provide a user-friendly interface that interacts with the Java diagnostic command utility, which can be used to force Java garbage collection. The JConsole monitoring tool provides a button on its memory management page that says Run Garbage Collection. Java Mission Control allows developers to select any jcmd switch -- including GC.run -- and execute the command at the click of a button.
However, these tools don't do anything unique in terms of Java garbage collection. They simply invoke the jcmd utility behind the scenes.
How to force Java garbage collection
While a developer can never actually force Java garbage collection, there are ways to make the JVM prioritize memory management functions. In review, five ways to try and force Java garbage collection are:
- Call the System.gc() command.
- Call the getRuntime().gc() command.
- Use the jmap command.
- Use the jcmd command.
- Use JConsole or Java Mission Control.
Java memory management
If developers find themselves in a position where they need to force Java garbage collection, there's probably a more nefarious problem plaguing the Java apps.
In those situations, it makes sense to turn on Java Flight Recorder and inspect the runtime after the crash, with an eye toward memory leaks or threads over-allocating an object. After the developer fixes the underlying problem, the need to force Java garbage collection will go away.