我目前正在查看这个愚蠢的小测试类的堆转储(在main方法的最后进行):

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));
        }
    }
}


现在,我试图找出如何计算对objects中特定类的引用的数量。如果这是一个SQL数据库,那将很容易:

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;


结果:

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


经过研究,我发现可以构造一个Eclipse MAT OQL查询,该查询为我提供了涉及的类:

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


las,这不包括它们的数量,OQL似乎不支持GROUP BY子句。任何想法如何获取此信息?

编辑添加:实际上,添加到Set的对象(显然不是Set实现本身)都不受我的控制。因此,很抱歉,不允许修改RefObj1RefObj2

Edit2:我发现这个related question有关在jvisualvm中使用OQL,但事实证明OQL实际上是在堆转储时释放的Javascript。我也可以这样。但是,玩它并没有为我带来任何结果。如果情况发生变化,我将更新问题。

最佳答案

打开直方图视图(有一个工具栏按钮,看起来像条形图)。
在直方图视图的第一行显示“ Regex”的地方,键入WeakReference过滤视图。
找到java.lang.ref.WeakReference行,右键单击,然后选择“按类显示对象”->“按传出引用”。
结果视图应总结所引用的对象,并根据需要按类分组。 “对象”列应指示每个类的实例数。

09-25 21:43