About Querying Objects from a Heap Dump…
The Memory Analyzer has powerful views to analyze a Java heap dump. But what if you look for those odd objects? Here the build-in Object Query Language (OQL) comes to the rescue. This blog introduces the basic syntax, commonly used queries and practical hints that help you dissect and analyze your objects.
The object query language (OQL) is very similar to SQL. Just think of classes as tables, objects as rows and attributes as columns. So, let’s open the OQL view (4th button from the left) and start with a very simple query (No Dump?):

SELECT * FROM java.lang.String
Alternatively, we can select the fields to be displayed:

SELECT toString(s), s.count, s.value
FROM java.lang.String s
So far, so good. But often, one needs to throw in some inheritance information. For example, the following query will not return any objects because java.lang.ref.Reference is an abstract class:
SELECT * FROM java.lang.ref.Reference
We could select the class using a regular expression (knowing that the most prominent sub-classes are WeakReference and SoftReference). Do do this, we place the class name in quotes:
SELECT * FROM "java\.lang\.ref\..*Reference"
While the regular expression is helpful to select a bunch of objects based on their package (à la “com\.my\.stuff\..*”), we rather use the instanceof keyword to select all objects of the Reference and its sub-classes:
SELECT * FROM INSTANCEOF java.lang.ref.Reference

We can easily group the resulting objects as histogram by clicking on the right most button:

Example: Investigating Soft Reference
Instead of looking at the Reference objects themselves, we now want to look at the referents, i.e. the object in the referent field. For example, objects only referenced via soft references are garbaged collected when the GC algorithm decides that memory is too low to keep the objects alive.
SELECT DISTINCT OBJECTS referent
FROM INSTANCEOF java.lang.ref.SoftReference
The DISTINCT keyword ensures that we do not include objects multiple times if more than one SoftReference refers to it. The OBJECTS keyword tells OQL to interpret the referent field as objects. This way we get a list of objects that we can browse into, group by class, etc.
Because such an analysis is commonly used, we have included this analysis in the menu: Java Basics -> Reference -> Soft / Weak / Finalizer References Statistics.
Now, let’s refine the query to limit the list to those objects referenced by the WeakReference only. This is interesting, because objects might be strongly referenced through another chain and therefore cannot be garbage collected. We extend the WHERE clause to (i) exclude null referents (probably already garbage collected) and (ii) include only objects with one inbound reference (which then must be the WeakReference):
SELECT DISTINCT OBJECTS r.referent
FROM INSTANCEOF java.lang.ref.SoftReference r
WHERE r.referent != null
AND inbounds(r.referent).length = 1
The inbounds() function returns an array with the objects referring to the given subject. Other functions are
- outbounds() to list the outgoing references,
- classof() for the class of the object and
- domiators() for the objects immediately dominated.
As you noticed, this last OQL query excludes objects which are referenced by multiple soft references. We would like to formulate the WHERE clause like AND include objects whose inbound references are only by weak or soft references objects. Here we reach the current (?!?) limit of our OQL implementation: the syntax includes an IN keyword. Unfortunately that does not work on two sets of objects but requires a single object on the left-hand side.
Not all is lost though, because the Soft / Weak / Finalizer References Statistics mentioned above also displays a histogram of objects that would be garbage collected if the referent edge in the object graph would not exist. This way you can answer the questions: “What are the objects kept alive only through soft references?”
OQL and Other Inspections
The object graph is often too complex for a SQL-like query. For example, try to extract the key-value pairs of an hash map via OQL - pick all buckets and then follow the overflow chain inside the buckets. For tasks like these, the Memory Analyzer offers pre-build inspections. And all of those inspections can also take an OQL query as an input parameter:

History of Queries
Every OQL query is added to the Navigation History. Open this view from the Window and re-run queries simply by double-clicking:

Help! There is no GROUP BY
This is the most frequently requested feature about our OQL implementation in the Memory Analyzer: GROUP BY. Unfortunately, I haven’t come around implementing this even though I have the bits and pieces together already. Also, the lack of this feature didn’t really hurt so much because there are two very powerful grouping features which fulfill most of our GROUP BY needs: The first is the Show as Histogram button which groups a set of objects by class and/or class loader. The second is the Java Basics -> Group By Value inspection, which groups a set objects by the value of an arbitrary attribute.
In the dialog, we choose all java.util.ArrayList and group the objects by the value of the size field.
As you already know from the examples above, we could specify the object set as input for grouping by using an OQL query.
Round Up
This was a quick introduction to OQL inside Memory Analyzer. The help pages include some more details of what functions are available and what properties can be queried. If you have questions how to formulate a specific query, let me know by posting into our newsgroup.
Posted September 3rd, 2008 by Andreas Buchen in category: Memory Analyzer
You can leave a response, or trackback from your own site.
2 Responses to “About Querying Objects from a Heap Dump…”
Leave a Reply
You must be logged in using your Eclipse Bugzilla account to post a comment.




Sam Says:
August 4th, 2009 at 11:06 pm
Hi..what is the syntax to retrieve a particular array element? for example, if I want to get the value of some string that is stored in as the third entry of an array.
Andreas Buchen Says:
August 17th, 2009 at 10:11 am
As of today, it is not possible to retrieve a particular array element. I have created this bugzilla entry to track this feature request: https://bugs.eclipse.org/bugs/show_bug.cgi?id=286771