Tracking Memory Leaks in Java
Tracking Memory Leaks in Java
Most "memory leaks" in Java are caused by references to objects that are no longer needed—if an object is still being referenced, then it cannot be finalized, and the memory used by it is never released. Continuing to create objects and forgetting to de-reference them when they're no longer needed creates memory leaks.
For example, consider the following code:
public class MemoryTIP { public static void main(String[] args) { ArrayList al=new ArrayList(); al.add(new myObject()); al.add(new myObject()); al.add(new myObject()); myObject.printMem(); //We can see that Objects are not freed. al.clear(); myObject.printMem(); //Ah yes, Objects are released. } } class myObject { public static int OBJC; public static int OBJD; {OBJC++;} //When an Object is created, we increase this counter public void finalize(){OBJD++; } // When an Object is finalized we decrease this counter /** * Print the Objects created and finalized * */ static void printMem() { System.gc(); System.out.println("created "+OBJC+" finalized "+OBJD); } }
When this code is run, its output is:
created 3 finalized 0 created 3 finalized 3
The output shows that after the first garbage collection, the three objects are still not free. However, when the ArrayList is cleared, you can free the objects
If you suspect that an object is not being dereferenced, thus causing a memory leak, try adding the following code to the class:
public static int OBJC; public static int OBJD; {OBJC++;} public void finalize(){OBJD++; } static void printMem() { System.gc(); System.out.println("created "+OBJC+" finalized "+OBJD); }
This will track the creation and finalization of the object. Calling the printMem() method periodically (or, if testing a GUI, have a button that calls it) helps identify when the leak may be occuring. Using this technique, you can spot memory leaks in Swing components. For example, JDialog will not be finalized until after the dispose method is called.