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.
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.*
References
- Diagnosing Java.lang.OutOfMemoryError (Xml and More)
- Memory Analyzer Downloads
- The stand-alone Memory Analyzer is based on Eclipse RCP.
- Can find the update site here too.
- Diagnosing Heap Stress in HotSpot (Xml and More)
- Querying Heap Objects (OQL)
- Export Data
- 10 Tips for using the Eclipse Memory Analyzer
- Analyzing a Heap Dump Using Object Query Language (OQL)
- Basic Tutorial of MAT
No comments:
Post a Comment