DEV Community

loading...

Effective Java: #7 Obsolete object and memory leak

Tin Trinh
Fullstack Software Engineer, love automation, coding, writing.
・2 min read

Java is the Garbage Collector programing language. What does that mean to you?

I mean that the language will take care of cleaning the unused objects in your program. If you come from a language like C/C++ you will feel that this is like a superpower because you don't have to manually clear the memory for the objects that you don't use anymore (the task that the developer keeps forgetting a lot).

Java did the magic through its Garbage Collection algorithm. There are a lot of them currently but basically it will check for the reference of the currently executed program with the objects that exist in the heap. If there is any object that wasn't referenced by the program, it will clear those objects as it considers those objects as garbage.

Let's consider this example, that I took from the book:

class PoolObjects {
   private static int DEFAULT_POOL_SIZE = 100;
   private int size = 0;
   private static Object[] pools;

   public PoolsObjects() {
      this.pools  = new Object[DEFAULT_POOL_SIZE];
   }

   public void add(Object o) {
      this.ensurePoolSize();
      this.pools[this.size++] = o;
   }

   public Object pop() {
      if (this.size == 0) {
         throw new EmptyPoolException();
      }
      Object r = this.pools[--size];
      return r;
   }

   private void ensurePoolCapacity() {
      if (this.pools.length = this.size) {
         this.pools = Arrays.copyOf(this.pools, 2 * size + 1);
   }
}

In the above example, there is a leaking memory point that is very subtle. As you can reason, as we decrease the size of the array, the element that has an index less than the size value will be inactive or should be discarded and clear by the GC. But actually it won't be because that object still gets referred by the pools variable.

One way to fix the problem is nulling out the element that hasn't been referred anymore.

public Object pop() {
      if (this.size == 0) {
         throw new EmptyPoolException();
      }
      Object r = this.pools[--size];
      this.pools[size] = null; // Explicitly nulling out the element at size index.
      return r;
   }

I would like to conclude the blog with some commonplace that memory leak could happen.

  1. The application that manages the memory by itself. The example above
  2. The application that uses caches. The object cached could stay in the memory forever.
  3. The listener or callback that registers but not dis-register.

Discussion (0)