how2examples.com
Home - Introduction to Java Programming

Automatic Garbage Collection

The JVM dynamically handles the allocation and deallocation of memory to store the details of objects used in the lifetime of an application. All objects are stored in a part of memory called the heap. Differant objects require differant amounts of storage space depending on their complexity.

The deallocation of memory when an object is no longer used is the responsibility of the garbage collector - a low-priority background thread of the JVM. The garbage collector identifies an object as no longer used, and so eligible for garbage collection, when the object is no longer accessiable from any live threads. Once an object is identified as eligible for garbage collection, the garbage collector deallocates the memory used to represent the object. Once memory has been unallocated it is then free to be allocated to new objects.

Monitoring Memory Usage

It is possible to monitor the amount of memory used by the JVM. java.lang.Runtime has freeMemory(), totalMemory() and maxMemory() methods.

Contents of MemoryExample.java:
public class MemoryExample {
   public static void main(String[] args) {
      Runtime r = Runtime.getRuntime();
      System.out.println("freeMemory()  " + r.freeMemory());
      System.out.println("totalMemory() " + r.totalMemory());
      System.out.println("maxMemory()   " + r.maxMemory());
   }
}
Command to compile MemoryExample.java:
javac MemoryExample.java
Command to run MemoryExample:
java MemoryExample
Output from running MemoryExample:
freeMemory()  4971424
totalMemory() 5177344
maxMemory()   66650112

Tuning Heap Size

Most JVMs provides a way to tune the size of the heap using parameters specified at startup. The -Xmx parameter sets the maximum possible size of the heap. The -Xms parameter sets the initial size of the heap.

Command to compile MemoryExample.java:
javac MemoryExample.java
Command to run MemoryExample:
java -Xmx512m -Xms256m MemoryExample
Output from running MemoryExample:
freeMemory()  266072200
totalMemory() 266403840
maxMemory()   532742144

System.gc() and Runtime.getRuntime().gc()

Although how and when garbage collection will occur is controlled by the JVM, applications can "suggest" a garbage collection by calling System.gc() or Runtime.getRuntime().gc().

Contents of GarbageCollectExample.java:
import java.util.*;

public class GarbageCollectExample {
   public static void main(String[] args) {
      // Populate List with lots of Objects.
      List<Object> l = new ArrayList<Object>();
      for (int i=0; i<1000000; i++) {
         l.add(new Object());
      }

      Runtime r = Runtime.getRuntime();

      System.out.println("freeMemory() before: " + r.freeMemory());

      // Remove reference to List and call Runtime.gc().
      l = null;
      r.gc();

      System.out.println("freeMemory() after:  " + r.freeMemory());
   }
}
Command to compile GarbageCollectExample.java:
javac GarbageCollectExample.java
Command to run GarbageCollectExample:
java GarbageCollectExample
Output from running GarbageCollectExample:
freeMemory() before: 8683096
freeMemory() after:  20173040

The java.lang.OutOfMemoryError class

Even with automatic garbage collection it is still possible for Java applications to run out of memory. If an application maintains references to a large number of objects then they will not be garbage collectable and eventually there will not be enough free memory to create any new objects. When the JVM has run out of memory a java.lang.java.lang.OutOfMemoryError will be thrown.

Contents of OutOfMemoryErrorExample.java:
import java.util.*;

public class OutOfMemoryErrorExample {
   public static void main(String[] args) {
      List<Object> l = new ArrayList<Object>();
      while (true) {
         l.add(new Object());
      }
   }
}
Command to compile OutOfMemoryErrorExample.java:
javac OutOfMemoryErrorExample.java
Command to run OutOfMemoryErrorExample:
java OutOfMemoryErrorExample
Output from running OutOfMemoryErrorExample:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
   at java.util.Arrays.copyOf(Arrays.java:2760)
   at java.util.Arrays.copyOf(Arrays.java:2734)
   at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
   at java.util.ArrayList.add(ArrayList.java:351)
   at OutOfMemoryErrorExample.main(OutOfMemoryErrorExample.java:7)

Java Memory Spaces

Local (method) variables (primitives or references to objects) go on the stack. Objects and their fields are stored in the heap. Class definitions are stored in the permanent generation (also known as the permgen space).

The java.lang.ref package

The java.lang.ref package contains reference-object classes that allow a limited degree of interaction with the garbage collector. A reference object allows a program to maintain a reference to another object in a way that does not stop the referenced object from being garbage collected. The collections API includes a WeakHashMap class - which may be useful when implementing memory-sensitive caches.


See Also