Tuesday, January 14, 2014

Eclipse MAT: Querying Heap Objects Using OQL

This article is a follow-up of [1]. Here we continue to explore on how to investigate memory leaks of an application using Memory Analyzer.[2]


Querying Heap Objects (OQL)


Memory Analyzer allows you to query the heap dump[3] with custom SQL-like queries (OQL). OQL represents classes as tables, objects as rows, and fields as columns:[4]

SELECT *
FROM [ INSTANCEOF ] <class name="name">
[ WHERE <filter-expression> ]
</filter-expression></class>To open an OQL editor use the toolbar button :

For instance, we have used the following SQL statement:
select * from java.lang.String where toString().startsWith("http://xmlns.oracle.com/bpel")

to query String objects with a certain prefix (i.e., "http://xmlns.oracle.com/bpel") and calculate the total size of retained heap associated with the interested objects.  Note that you need to press red "!" button to execute the OQL.



Shallow vs. Retained Heap


As shown in the Figure, two sizes of an object are displayed in the Result area:
  • Shallow heap
  • Retained heap

Generally speaking, shallow heap of an object is its size in the heap and retained size of the same object is the amount of heap memory that will be freed when the object is garbage collected. In other words, retained heap of object X is the sum of shallow sizes of all objects in the retained set of X, the set of objects which would be removed by Garbage Collector when X is garbage collected.

As said in [6], while Shallow Heap can be interesting, the more useful metric is the Retained Heap. For example, you can benchmark retained sizes of interested objects before and after your code optimizations. Below, we will show how to compute the total retained size of our interested objects.


Exporting to CSV...


Analyzed data can be exported from the heap editor by:[5]
  • Using the toolbar export menu (you can choose between export to HTML, CSV, and TXT)

Let's say we have exported it to a CSV file named RetainedHeap.txt.

Importing CSV File into Excel


You can use Java code to parse the CSV file and compute the retained heap of interested objects. An alternative way is using Excel, which is demonstrated here.

First, you open RetainedHeap.txt and specify both comma and space as the delimiters of fields.


Then, select all "Retained Heap" fields (shown in red) and compute the Sum as shown below:


Finding Responsible Objects


To investigate your potential memory leaks, it will be important to answer the following question:
Who has kept these objects alive?
To answer that, you can use Immediate Dominators (an Object X is said to dominate an Object Y if every path from the Root to Y must pass through X) from the context menu. This query finds and aggregates all objects dominating a given set of objects on class level. It is very useful to quickly find out who is responsible for a set of objects. Using the fact that every object has just one immediate dominator (unlike multiple incoming references) the tool offers possibility to filter "uninteresting" dominators (e.g. java.* classes) and directly see the responsible application classes.

For example, if your interested objects are char arrays. The immediate dominators of all char arrays are all objects responsible for keeping the char[] alive. The result will contain most likely java.lang.String objects. If you add the skip pattern java.* , and you will see the non-JDK classes responsible for the char arrays.

  

Bonus OQL Example


In the above OQL example, it shows that two columns were selected:
  • toString(s.sqlObject.actualSql)
  • s.@retainedHeapSize
from oracle.jdbc.driver.T4CPreparedStatement (alias: s).  Also, a filter was added (highlighted in red):
  • .*SELECT TerritoryResource.*

No comments: