Friday, March 9, 2012

Memory leaks in Java

I would like to discuss here a few points regarding memory management in Java.

As a C++ veteran, one of my favorite subjects is memory management provided for a programming language. One of the reasons why I've adopted Java is that its Runtime provides a state of art garbage collection mechanism.
Memory allocation in C++ was sometimes a burden, always prone to memory leaks and dangling pointers. Even when C++11 introduced better garbage collection through smart pointers, automatic garbage collection in Java becomes a superior concept and programming is achieved at a higher level. This new level means that you don't need to deal with memory management at all or so it seems.

Is it possible to leak memory in Java?

Well the answer here is YES for the following reasons:
  • Java as a garbage collected languages have difficulty to release scarce system resources (database handlers, graphic resources, file handlers etc.), as it is difficult to define (or determine) when or if a finalizer method might be called.    
  • Java uses manual memory management for scarce system resources; any object which manages graphic resources for example is expected to implement dispose method, which releases any such resources and marks the object as inactive. Usually developers are expected to invoke dispose manually as appropriate; to prevent "leaking" of scarce graphics resources.
  • If a program holds a reference to a heap chunk that is not used during the rest of its life, it is considered a memory leak because the memory could have been freed and reused. The garbage collector won't reclaim it due to the reference being held by the program. A Java program could run out of memory due to such leaks.
Let's try next to come up with some specific examples of memory leaks:
  • Not calling the finalize method (depending how Java implements finalizers) to release graphics resources.
  • A database connection which is never released
  • A file handler open and never closed
  • The application creates a long-running threads or thread pool.
  • The thread loads a class using ClassLoader.
  • Caches or reflective utilities some times hold a reference to ClassLoader or a variant of ClassLoader (like WebappClassLoader, ThreadContextClassLoader). When those references cannot be claimed memory leak happens.
  • The class allocates a large chunk of memory, stores a strong reference to it in a static field, and then stores a reference to itself in a ThreadLocal. Allocating the extra memory is optional (leaking the Class instance is enough), but it will make the leak work that much faster.
  • The thread clears all references to the custom class or the ClassLoader it was loaded from.

1 comment:

  1. Java 7 has a number of language enhancements. One of the new features is automatic resource management.
    Interestingly enough this new feature manages the resources automatically. In order to handle in this way a resource it must implement java.lang.AutoCloseable. For more detail follow the article: http://radar.oreilly.com/2011/09/java7-features.html.

    ReplyDelete