Java Runtime class - Invoke the Java garbage collector

Note: This article is very old, like 1990s-old. In the 90s we did things like this, but manually manipulating theJava garbage collector in the 201x years is not a best-practice. That being said, I'm leaving this article here for historical reasons.

Summary: This article demonstrates how to use the Java Runtime class to invoke the Java garbage collector, and shows the results of running the Java Runtime freeMemory method in an example class.

Introduction

As you know, the Java Virtual Machine (JVM) takes care of memory management for you. That's one of the beauties of Java - life as a Java developer is easier than C/C++ because you don't have to worry (as much) about memory management, and making all of the mistakes associated with memory management, such as forgetting to free dynamically allocated memory.

Generally speaking (and ignoring the differences between implementations and versions) the JVM works by performing garbage collection when it needs more memory to continue execution. Though your program may lose a reference to an object - thereby making it a candidate to be reclaimed - there's no guarantee the JVM will reclaim that memory.

Although you can't tell Java to explicitly reclaim the memory of a specific de-referenced object, there is a way to tell the JVM to perform garbage collection, which may result in the desired memory being reclaimed. It's a very simple technique, and I was inspired to use it when I was developing a Java-based editor on a computer with limited memory itself.

Invoking the Java garbage collector

Invoking the Java garbage collector requires a simple two-step process. First you create a Java Runtime object. If you haven't used them before, Runtime objects let you interface with the environment in which your application is running. Then, after creating the Runtime object, you'll invoke the gc() method ("garbage collector") of the Runtime class.

Written in Java, these two steps look like this:

Runtime r = Runtime.getRuntime();
r.gc();

That's all that's required in this technique. Let's look at how this works in a test program.

A simple test program

Listing 1 shows a simple program that tests this technique. Although it may look a little complicated, all we do is grab a bunch of memory and then release it. At various stages in the program, we use the freeMemory() method of the Runtime class to determine the amount of free memory in the system.

public class GCTest {

   final int NELEMS = 50000;

   void eatMemory() {

      int[] intArray = new int[NELEMS];

      for (int i=0; i<NELEMS; i++) {
        intArray[i] = i;
      }

   }

   public static void main (String[] args) {

      GCTest gct = new GCTest();

      // Step 1: get a Runtime object
      Runtime r = Runtime.getRuntime();

      // Step 2: determine the current amount of free memory
      long freeMem = r.freeMemory();
      System.out.println("free memory before creating array: " + freeMem);

      // Step 3: consume some memory
      gct.eatMemory();

      // Step 4: determine amount of memory left after consumption
      freeMem = r.freeMemory();
      System.out.println("free memory after creating array:  " + freeMem);

      // Step 5: run the garbage collector, then check freeMemory
      r.gc();
      freeMem = r.freeMemory();
      System.out.println("free memory after running gc():    " + freeMem);
   }
}

Listing 1 (above): The GCTest program (GCTest.java) demonstrates how you can manually invoke the garbage collector of the JVM.

To compile this program at the command line, just enter this command:

javac GCTest.java

Then, when you're ready to run the program, use this command to invoke the Java interpreter (the JVM):

java GCTest

Running this program with the compiler and interpreter supplied with VisualCafe 2.5 on a Windows95 computer, I get the following output:

free memory before creating array: 4054912
free memory after creating array:  3852496
free memory after running gc():    4064184

Running the same byte code on various Unix workstations, I get different numbers, but a similar amount of memory consumption indicated by the second print statement.

As you can see, the memory initially consumed by our array in the eatMemory() method is not immediately reclaimed by the interpreter. Only after we call the gc() method is the memory reclaimed, even though the eatMemory() method has already been invoked, and control has returned to the main() method.

Download the source code

If you'd like to download the source code shown in Listing 1, just click here, and the Java source code will be displayed in your browser. Then just use the "File | Save As" option of your browser to save the source code to your system.

Permalink

it's very easy to understand i appreciate ur post!

Permalink

I now understand practically what is gc.
Your explaination is fantastic,clear.

Permalink

In 99.99% of the cases, this is bad advice. What may look like a good time to tell the JVM to explicitly perform a GC, might actually slow down the entire app when a GC. The general rule is that you *don't* know when a GC is appropriate and should let the JVM (the collector itself) decide when it's appropriate. If you know that the default GC is doing something wrong (taking too long, not frequent enough, wrong times, etc..), maybe even it's the wrong GC type for your app....tune it via the command line switches, not with your application. Explicitly invoking a GC is more than likely just going to do the wrong thing.

I have had more than a few libraries that had this Runtime.gc() code in it that completely ruined performance. Do yourself a favor and always run your app with XX:+DisableExplicitGC like Sun/Oracle advises you to do : http://docs.sun.com/source/819-0084/pt_tuningjava.html and forget about GC from within the app. Tune it outside of the app.

Add new comment

The content of this field is kept private and will not be shown publicly.

Anonymous format

  • Allowed HTML tags: <em> <strong> <cite> <code> <ul type> <ol start type> <li> <pre>
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.