Eclipse堆散步

时间:2010-08-11 16:49:48

标签: eclipse debugging heap

调试Java代码时,Eclipse有一个功能,允许它查找给定类型的所有实例(通过Variables窗口中的上下文菜单)。有没有办法以编程方式过滤这些?例如,我想要FieldInstruction类的所有实例

the_instance.getType().getName().equals("somestring")  

评估为真。

当我试图调试已经应该枚举所有实例的代码时,只需创建我自己的代码,遍历类所在的树结构就会失败目的。我真的希望能够通过Display或Expressions窗口进行过滤。

1 个答案:

答案 0 :(得分:2)

我最终创建了一个相当hacky“InstanceRegistry”类。在我想跟踪的每个类类型的构造函数中,我把

InstanceRegistry.register(this);

这甚至可以在所有超类和接口下“注册”实例。

迭代实例(甚至可以在Eclipse Display窗口中完成):

for(Object instance : InstanceRegistry.getInstances(FieldInstruction.class)) {
    //do something
}

InstanceRegistry类的源代码:

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

public class InstanceRegistry {
    private InstanceRegistry() {}

    private static HashMap<Class<?>, HashSet<WeakReference<?>>> instances = new HashMap<Class<?>, HashSet<WeakReference<?>>>();

    public static <T> Iterable<T> getInstances(final Class<T> type) {
        return new Iterable<T>() {
            public Iterator<T> iterator() {
                return new Iterator<T>() {
                    Iterator<WeakReference<?>> it = instances.get(type).iterator();
                    T item = find();

                    {
                        System.gc();
                    }

                    public boolean hasNext() {
                        return item != null;
                    }

                    private T find() {
                        WeakReference<T> fi;
                        while(it.hasNext()) {
                            fi = (WeakReference<T>) it.next();
                            if(fi.get() != null)
                                return fi.get();
                        }
                        return null;
                    }

                    public T next() {
                        T ret = item;
                        item = find();
                        return ret;
                    }

                    public void remove() {
                        throw new UnsupportedOperationException();
                    }
                };
            }
        };
    }

    private static void put(Class<?> type, WeakReference<?> instance) {
        HashSet<WeakReference<?>> list = instances.get(type);
        if(list == null) {
            list = new HashSet<WeakReference<?>>();
            instances.put(type, list);
        }
        list.add(instance);
    }

    public static void register(Object instance) {
        WeakReference<Object> inst = new WeakReference<Object>(instance);
        Class<?> c = instance.getClass();
        do {
            put(c, inst);
            for(Class<?> ci : c.getInterfaces()) {
                put(ci, inst);
            }
            c = c.getSuperclass();
        } while(c != Object.class);
    }
}