Search code examples
javaweak-referenceseclipse-memory-analyzer

Counting reference targets in a heap dump of Set<WeakReference>


I'm currently looking at the heap dump of this silly little test class (taken at the very end of the main method):

public class WeakRefTest {
    static final class RefObj1 { int i; }
    static final class RefObj2 { int j; }

    public static void main(String[] args) {
        Set<WeakReference<?>> objects = new HashSet<>();    
        RefObj1 obj1 = new RefObj1();
        RefObj2 obj2 = new RefObj2();
        for (int i = 0; i < 1000; i++) {
            objects.add(new WeakReference<RefObj1>(obj1));
            objects.add(new WeakReference<RefObj2>(obj2));
        }
    }
}

Now I'm trying to figure out how to count the number of references to a specific class in objects. If this were a SQL database, it'd be easy:

select objects.className as referent, count(*) as cnt
  from java.lang.ref.WeakReference ref 
    inner join heapObjects objects on ref.referent = objects.objectId
  group by objects.className;

Result:

referent | cnt
===================
WeakRefTest$RefObj1 | 1000
WeakRefTest$RefObj2 | 1000

After some research, I figured I can construct a Eclipse MAT OQL query that gives me the classes involved:

select DISTINCT OBJECTS classof(ref.referent) from java.lang.ref.WeakReference ref

Alas, this doesn't include their count and OQL doesn't seem to support a GROUP BY clause. Any ideas how to get this information?

Edited to add: In reality, none of the objects added to the Set (nor the Set implementation itself, obviously) are under my control. So sorry, modifying RefObj1 and RefObj2 isn't allowed.

Edit2: I found this related question about using OQL in jvisualvm but it turns out that OQL is actually Javascript unleashed at a heap dump. I'd be fine with something like that, too. But playing around with it hasn't produced results for me, yet. I'll update the question if that changes.


Solution

    1. Open the histogram view (there is a toolbar button for this, which looks like a bar graph).
    2. In the first row of the histogram view where it says "Regex", type WeakReference to filter the view.
    3. Find the java.lang.ref.WeakReference line, right-click, and choose "Show Objects By Class" -> "By Outgoing References".
    4. The resulting view should be summarize the objects being referred to, grouped by class as you require. The Objects column should indicate the number of instances for each class.