Eliminate obsolete object references in Java

What are Obsolete References in Java?

An obsolete reference is one that is kept around but will never be used. It prevents the object (obsolete reference refers to) from being eligible for garbage collection. It causes the memory leak.

What is a memory leak

A memory leak, in computer science, occurs when a computer program consumes memory but is unable to release it back to the operating system.

In Java programming, we can phrase memory leak like this:
When the Java object gets an obsolete reference and becomes not eligible for garbage collection then memory leak happens

Memory leaks can cause disk paging and even OutOfMemoryError.

Reasons of memory leak

There are many reasons for memory leak in Java. Here is a good article about creating the memory leak in Java.

According to effective java book, the memory leak can happen for the following reasons:

  • The source of memory leaks is caches
  • Memory leaks happen for listeners and callbacks
  • Obsolete references of objects can cause memory leaks
  • Whenever the class is managing its own memory, there are possibilities of memory leaks

How to remove obsolete references

The obsolete reference is a reference that will never be used and dereferenced again. So, setting it to null will make it eligible for garbage collection.

public Object pop() {
    if (size == 0)
        throw new EmptyStackException();
    Object result = elements[--size];
    elements[size] = null; // Eliminate obsolete reference
    return result;
}

Best way to remove obsolete reference

Eliminate the obsolete reference by falling it out of scope. Define each variable in the narrowest possible scope.

When should we null out a reference?

  • Whenever an element is free or inactive, any object references contained in the element should be nulled out.
  • Whenever we put object reference into a cache and leave it there. It will become irrelevant after a long time. We should occasionally remove the entries with Timer or ScheduledThreadPoolExecutor.
  • Using Listener and other callbacks that forget to deregister them explicitly. The best way is to store only weak references to them, by storing them in a WeakHashMap.
  • By using heap profiler a debugging tool to discover the memory leaks.