Querying Heap Objects (OQL)
Memory Analyzer allows you to query the heap dump with custom SQL-like queries (OQL). OQL represents classes as tables, objects as rows, and fields as columns:
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.
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 , 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:
- 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?
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.
- The stand-alone Memory Analyzer is based on Eclipse RCP.
- Can find the update site here too.