by Dr. Fank Munz
A sample chapter from Oracle WebLogic Server 12c: Distinctive Recipes
January 2013
There are zillions of commercial tools available that promise to detect memory leaks. Most of them only measure the growth of the number of objects and provide fancy graphics that show relations between objects.
A clever algorithm is available, implemented by the JVisualVM tools that come with the recent version of Oracle JDK 6 and 7.
Surviving generations is a metric indicating potential memory leaks by counting objects that are created over and over but never destroyed.
The metric measures the number of different ages for all objects allocated on the JVM heap from the start of the profiling session. The age of an object is defined as the number of garbage collections the object has survived.
So far the surviving generation's metric can only be accessed after the code is instrumented by the JVisiualVM tool.
Let's take a look at the following example where lots of objects are created but then destroyed after a while.
The lifetime of the objects (illustrated as horizontal bars) plotted over time, might appear as shown in the following diagram.
The diagram shows a pretty low number of surviving generations.
In the case of a memory leak this will be different. Objects are still created at various times, however, they keep living (due to a coding error) and are never collected.
So for the same number of objects, the number of different object ages (the surviving generations metric) is much higher.
VisualVM can be used to profile memory and calculate the surviving generations metric for all classes. In the screenshot below you can see the surviving generations displayed while profiling the memory usage of an application.
The surviving generations metric is shown on the right, the call tree of a method with a rather high surviving generations metric is shown on the left.
While the code was running, CPU and heap appeared as illustrated in the diagram below. The small memory leak in the code cannot be seen in the heap diagram.
The process for detecting a memory leak is demonstrated in the following video.
An example that can be directly run from the command line or NetBeans is available for download: LeakExampleBook.zip.
The code of the memory leak example can be called from a timer EJB which automatically fires every second.
@Schedule(hour = "*", minute = "*", second = "*/1")
public void callMe() {
//... call leaking method
System.out.println("memleak was triggered " + new Date());
}
JVisualVM is not available for JRockit. If you want to use the tool to detect a memory leak, you have to switch the JDK (which is not that difficult - have a look at Recipe 6).
The team merging the current JRockit with the Oracle JDK 7 is aware of the superior algorithm; however, it is not clear when (or even if) it will be included in the JRockit Mission Control toolset.
When trying the JVisualVM and the sample code, note that the algorithm depends on garbage collections. If your heap is too large there won't be any garbage collection for a long time, and therefore the surviving generation's metric remains at 1.
The recipe discussed here can be used when you are working with Oracle JDK 6 or 7 and looking for a free and efficient tool to track down a memory leak.
This recipe is not recommended for a production system, because the of the instrumenation the memory profiler performs on your code. The instrumenation process can significatnly slow application performance.
Dr. Frank Munz has more than 15 years experience as an IT architect, with proven expertise in Service Oriented Architecture, Enterprise Application Integration, and Java EE. In 2011 Dr. Munz earned Oracle Magazine's Technologist of the Year award in the Cloud Architect category. A prolific blogger, he is also the author of Middleware and Cloud Computing and Oracle WebLogic Server 12c: Distinctive Recipes.