public class MyClass {
private ArrayList list = new ArrayList();
public void addFoo( Object foo ) {
list.add( foo );
}
public void processFoo( Object foo ) {
// Get foo out of the list Object
fooRef = list.get( foo );
// Do something with fooRef ...
// Done with fooRef, destroy it
fooRef = null;
}
}
In this example, the addFoo() method adds an object named foo to the internal ArrayList. The processFoo() method loads foo out of the ArrayList, does something with it, and then destroys it. The problem is that while you may expect foo to be removed from the heap (or at least eligible for garbage collection), foo will, in actuality, remain in the heap, and its memory will never have a chance to be reclaimed. This is because the ArrayList is still maintaining its own reference to foo. When the processFoo() method calls the ArrayList’s get() method and assigns the object to fooRef, this simply introduces a new reference to the foo object. Now one reference is held by the ArrayList, and one reference is held by the fooRef. So when fooRef is set to null to destroy the reference, this only destroys the fooRef reference, not the ArrayList’s reference. The proper solution is to explicitly call the ArrayList’s remove() method to tell the ArrayList to destroy its internal reference to foo. Because of the nature of Java’s object management and how easy it is to inadvertently maintain lingering object references, memory leaks abound in Java applications.
Post a Comment