Title: Garbage Collection
Course: CPS 261: Advanced Java Concepts ~ DL & MM MASTER

Garbage Collection

Java automatically collects unused memory objects. Normally you shouldn't have to do anything to help Java do its job.

This chapter is primarily for understanding.

1. Java manages memory in a structure called a heap. A heap is memory global to all of your Java methods.
2. Your program does not directly deal with recovering unused memory. It's normally up to the Java Run Time System to determine when its time to recover unused memory. This is usually deferred until memory gets short enough that Java considers it necessary. The process of recovering unused memory is called the Garbage Collector.
3. When there is no pointer (or handle) to a particular object, it is now available for the Java Garbage collector. The code in your program determines when memory can be garbage collected. For example consider the following piece of code:

4.
  String s1 = "hello";
  String s2 = "goodbye";
  s1 = s2; // The "hello" hunk can now be garbage collected
  s2 = null;// The "goodbye" hunk is not available for garbage
            // collection because s1 now points to "goodbye
  s1 = "more junk";  // Now "goodbye" is available for garbage collection
  s1 = null; // now "more junk" can be garbage collected


5. Variables that go out of scope can be Garbage collected unless they are returned to a calling method. In the example below, r and str go out of scope when the getRect method exits. The String str can be Garbage collected, but "r" is returned and as long as the calling method hangs onto a pointer to this object it won't be Garbage collected.

class Rectangle
{ // minimal class
}

class ReturnedValues {
   public static void main(String [] args) {
      Rectangle rect = getRect();
      // rect is not available for Garbage collection as long as we
      // hang onto a Reference to it.
   }

   public static Rectangle getRect() {
      Rectangle r = new Rectangle();
      String str = " rectangle = " + r;
      System.out.println(r);
      return r;

      // str String can be garbage collected, but r can't
      // be Garbage collected until the calling program gets rid
      // returned value
   }
}



6. You can do something special when the Garbage Collector discovers that your object has no more references (hence it is available to be Garbage Collected). Just override the finalize method in the Object class called:
protected void finalize()
{
}

This method can be used to close a file that didn't get explicity closed by your code.
7. The implementation of the Garbage Collector can be implemented differently by each Java Run Time system.
8. The method often used by the Garbage Collector is called Mark-Sweep. At some point when free memory drops below some threshold, the Garbage collected marks all objects that have at least one reference. This can be done by looking at objects referenced by main or by the run routine of a Thread (we will talk about threads later). For each object found, we also need to recursively look at objects inside of the referenced objects. Once all of the "Reachable" or Referenced objects have been marked, the Garbage Collector can reclaim the memory associated with any object that isn't marked.
9. Explicitly calling the Garbage Collector. When the Garbage collector runs, it makes your system momentarily unresponsive. You might want to explicitly tell the Garbage Collector to free up unused memory so that you have a window of time where you should be running uninterrupted by Garbage Collection. Explicitly calling the Garbage Collector is done with either of the following:
System.gc();
OR
Runtime rt = Runtime.getRuntime();
rt.gc();
10. You can also suggest to the System to run all of the finalization code with the following (note this is a suggestion only to the JRE, and can be ignored by your JRE):
System.runFinalization( );
11. You can also find out how much memory is free and how much total memory is available, by calling the totalMemory( ) and freeMemory( ) methods in the Runtime class.
12. Watching the Garbage Collector kick in automatically:

import java.util.Date;
class GarbageFactory {
     public static void main(String [] args) {
        Runtime rt = Runtime.getRuntime();
        System.out.println("Total JVM memory: " + rt.totalMemory());
        Date d = null;
        int total = 0;
        while(true) {
           d = new Date();
           ++total;
           if(total % 500 == 0) {
              System.out.print("Objects: " + total);
              System.out.println(" Memory: " + rt.freeMemory());
           }
        }
     }
  }


13. Explicitly calling the Garbage Collector


  import java.util.Date;
  class CheckGC {
     public static void main(String [] args) {
        Runtime rt = Runtime.getRuntime();
        System.out.println("Total JVM memory: " + rt.totalMemory());
        System.out.println("Before Memory = " + rt.freeMemory());
        Date d = null;
        for(int i = 0;i<10000;i++) {
           d = new Date();
           d = null;
        }
        System.out.println("After Memory = " + rt.freeMemory());
        rt.gc();
        System.out.println("After GC Memory = " + rt.freeMemory());
     }
  }


14. Watching Finalizations:


  class ObjectWatch {
     public static int totalCreated;
     public static int totalFinalized;

     public ObjectWatch() {
        ++totalCreated;
     }

     public static void main(String [] args) {
        for(int i=0;i<20000;i++) {
           ObjectWatch ow = new ObjectWatch();
           System.out.print("Created: " + totalCreated);
           System.out.println(" Finalized: " + totalFinalized);
        }
     }

     protected void finalize() {
        ++totalFinalized;
     }
  }


Last Updated: September 2, 2002 4:24 PM