JVM memory shortage often leads to instability and slowdown of Java applications. Low memory error may not appear during the application testing, it will occur later in the production mode after a while when objects fill the Java heap, and Garbage Collector is not able to free up memory because all objects are live.
Localizing the cause of a memory leak is not a trivial task. There could be data structures that keep references to unused objects, structures that reserve much more space than they need, data duplication, etc. To investigate a cause, you need to take the heap dump and explore it in a memory analyzing tool.
Making a Heap Dump with Zulu Mission Control
A heap dump is a snapshot of all the objects in the JVM heap at a certain point in time.
To make a heap dump, right-click the JVM in the JVM Browser tab and choose Dump Heap from the context menu. The created Heap Dump file will be saved in the current working directory of the JVM instance in the following format
dump_<connection time>_<recording number>.hprof.
Zulu Mission Control will automatically analyze the created dump and display the results in the JOverflow dashboard. If you want to analyze a specific heap dump, select File > Open File from the main menu and locate the file.
JOverflow is the ZMC plugin that performs the heap dump analysis and reports where the JVM memory might be getting wasted. It scans the entire heap, automatically identifies objects matching specific anti-patterns, aggregates objects with the same types of problems, and calculates overhead values.
Figure. Outline and Automated Analysis: JOverflow dashboard
The JOverflow dashboard is split into four quadrants:
Object Selection table lists the objects types found in a heap. You can see the summary information for every type of object associated with a particular type of overhead: memory used, memory wasted, and the number of objects.
Note: An object can have different types of errors and therefore belong to several overhead types.
Referrer table shows aggregated reference chains for the selected item. You can drill down on this table to get to the required set of objects.
To reset the selections in the Referrer table, right-click in the table.
Class histogram displays the list of classes for the selected element and the pie-chart that visualizes memory allocation. You can use this histogram to filter on a class and to reduce the number of objects involved.
To reset the selections in the Class histogram, click the button displaying the selection you've made.
Ancestor Referrer histogram displays the objects grouped by the closest ancestor referrer. The pie-chart visualizes memory allocation. You can use this histogram to reduce the number of objects by looking after the referring chain to each object. If you want to find the instances of classes and objects belonging to specific packages, use the Ancestor Prefix filter. It groups the objects by the closest referrer that is matching the pattern.
To reset the selections in the Ancestor Referrer histogram, click the button displaying the selection you've made.
To reset all the selections you've made on the dashboard, click the Reset button in the upper right corner of the JOverflow window.
Example: Searching for Memory Leaks with JOverflow
Let's analyze the Heap Dump of Zulu Mission Control displayed below.
Select the Overhead
inspect the Overheads column in the Object Selection table for the highest percent, which indicates a possible memory leak.
You can see that we are wasting 5% of our used heap with 23247 small collections here.
Select the Small Collections overhead to track the potentially leaking classes.
Now, if you look at the Class histogram, you can see that HashMap is on the top of the list, and it accounts for 3% of the heap.
Figure. Heap Analysis: Step 1
Filter on the Class
When the potentially leaking HashMap class is identified, click on it to narrow down the number of investigated problem objects to 8446 and use the Referrer table to identify the source of the leaking object.
Figure. Heap Analysis: Step 2
Drill down the Referring Chain
Collections$UnmodifiableMap.min the Referrer table. You can see that these collections keep 6163 objects.
Figure. Heap Analysis: Step 3
You want to know where these small collections are being used, so you click the top entry in the Referrer tree-table. The reference chain opens, and the problem object is at the bottom of the chain. Now you can inspect the code of the Class of this object for possible problems with small collections.
Figure. Heap Analysis: Step 4
Now that you have a basic understanding of the JOverflow dashboard navigation, you can begin using it for investigations on your own.
- Investigate why there are too many objects of a specific type and find out what holds links to them.
- Debug your application or optimize it for the heap consumption.
- Optimize your application to reduce memory leaks and Garbage Collector load.