Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Plug memory leaks in enterprise Java applications

Strategies for detecting and fixing enterprise memory leaks

  • Print
  • Feedback

The Java automatic garbage collection process typically operates as a low-priority thread that constantly searches memory for unreachable objects, objects not referenced by any other object reachable by a live thread. Different JVMs use different algorithms to determine how to collect garbage most efficiently.

In the JVM, memory is allocated in two regions:

  • Stack: Where local variables (declared in methods and constructors) are allocated. Local variables are allocated when a method is invoked and de-allocated when the method is exited.
  • Heap: Where all objects created with the new keyword are allocated. Since local variables are few in number, only primitive types and references, usually the stack will not overflow, except in cases of unusually deep or infinite recursion. The JVM throws a Java out-of-memory error if it is not able to get more memory in the heap to allocate more Java objects. The JVM cannot allocate more objects if the heap is full of live objects and unable to expand further.

Causes of memory leaks in Java

The four typical causes of memory leaks in a Java program are:

  1. Unknown or unwanted object references: These objects are no longer needed, but the garbage collector can not reclaim the memory because another object still refers to it.
  2. Long-living (static) objects: These objects stay in the memory for the application's full lifetime. Objects tagged to the session may also have the same lifetime as the session, which is created per user and remains until the user logs out of the application.
  3. Failure to clean up or free native system resources: Native system resources are resources allocated by a function external to Java, typically native code written in C or C++. Java Native Interface (JNI) APIs are used to embed native libraries/code into Java code.
  4. Bugs in the JDK or third-party libraries: Bugs in various versions of the JDK or in the Abstract Window Toolkit and Swing packages can cause memory leaks.

Detection of memory leaks

Some approaches to detecting memory leaks follow in the list below:

  1. Use the operating system process monitor, which tells how much memory a process is using. On Microsoft Windows, the task manager can show memory usage when a Java program is running. This mechanism gives a coarse-grained idea of a process's total memory utilization.
  2. Use the totalMemory() and freeMemory() methods in the Java runtime class, which shows how much total heap memory is being controlled by the JVM, along with how much is not in use at a particular time. This mechanism can provide the heap's memory utilization. However, details of the heap utilization indicating the objects in the heap are not shown.
  3. Use memory-profiling tools, e.g., JProbe Memory Debugger. These tools can provide a runtime picture of the heap and its utilization. However, they can be used only during development, not deployment, as they slow application performance considerably.

Causes of memory leaks in enterprise Java applications

In the subsequent sections, I analyze some causes of memory leaks in enterprise Java applications using a sample application and a memory profiling tool. I also suggest strategies for detecting and plugging such leaks in your own projects.

  • Print
  • Feedback

Resources