Memory leaks in Java programs are just as much of an issue as they are for programs written in any other language. Despite the garbage collector (GC), there are situations where the GC cannot remove objects because they are still referenced. The first problem is identifying a memory leak and the second problem is locating the class responsible. This post will show you, how to identify and locate a memory leak in a Java program running in the JVM server in CICS.
One of the advantages of using Java as a programming language is that memory management is less of an issue for the developer, simply creating objects and letting the garbage collector reuse the memory when they are no longer needed. Even with the garbage collector, however, memory leaks can still occur in Java programs when references to objects are retained.
This situation might arise when a program creates references to objects without ever removing them. One example is the use of collections where objects are added to a collection for processing, but once stored and processed, never get removed. This means the application has an ever growing number of references to objects it no longer needs.
Typical heap usage remains constant over time after a program has finished starting up. Heap usage grows as more objects are created and more space on the heap is used. The GC can run and reclaim space occupied by objects that are no longer needed. When a Java program is leaking memory, heap usage grows over time because there are objects being created that the GC cannot clean up. This eventually results in a java.lang.OutOfMemoryError.
The IBM Support Assistant (ISA) is a complimentary software offering that provides a workbench for hosting other tools to assist with problem determination. The ISA can be downloaded for free from here.
After you download ISA, you have to customize the workbench with the tools specific to your activities. There are many tools available to the IBM Support Assistant that you may like to investigate. This article, however, looks at the Health Center and the Memory Analyzer tools. To add these tools click the Analyze Problem button on the workbench homepage. A list of the currently installed tools is displayed. To add Health Center and Memory Analyzer, click the Find New Tool Add-ons link. Then check the boxes next to:
- IBM Monitoring and Diagnostic Tools for Java - Health Center
- IBM Monitoring and Diagnostic Tools for Java – Memory Analyzer
Follow the installation wizard and restart ISA when prompted.
Connecting the Health Center
The first requirement is to modify the JVM profile for the JVM server. Add the -XhealthCenter option to the profile, disable and then enable the JVM server resource to register the changes.
The Health Center agent listens on a specific port. To find the port you must look in the dfhjvmerr file for your JVM server. This file is located in the directory specified by the WORK_DIR option in the JVM profile. Look for the following line to indicate which port you should connect to:
INFO: Health Center agent started on port 1972.
To connect the Health Center, launch ISA and click the Analyze Problem button on the homepage. From the list of installed tools select the Health Center, following the wizard through and entering the host name and port when required.
After completing the wizard, the Health Center connects to your JVM server and begins to collect monitoring data.
Monitoring the JVM
Once the tool has initialized, the links on the status tab become active. Each link shows you some information related to a different perspective of the JVM that is useful in different situations. This article focuses on the Garbage Collection perspective to demonstrate how it can be used to determine a memory leak.
Click on the Garbage Collection link to display a tab showing current heap usage in the JVM server.
In this example, the Health Center has been connected to a JVM server in which the sample program is running that contains a memory leak. The chart shows that heap usage is increasing over time, as the GC cannot remove all of the objects that are being created. It is important to observe the memory use increasing over time in this way because a java.lang.OutOfMemoryError could also be caused by a Java program that requires more memory than the JVM has allocated for its maximum heap size, which could be fixed by increasing the heap size of the JVM.
Select Request a dump... from the Monitored JVM menu.
When the dump is on your local machine you can use the Heap Analyzer to determine which classes are responsible for the usage.
After you select the heap dump, you are provided with a choice of report that can be generated. The report used here is the default Leak Suspects report. This report displays a pie chart showing the objects responsible for using the largest portions of the heap. These are often a good place to start an investigation into where a problem may be.