Eclipse heap walk - PullRequest
       7

Eclipse heap walk

2 голосов
/ 11 августа 2010

При отладке кода Java в Eclipse есть функция, позволяющая находить все экземпляры заданного типа (через контекстное меню в окне «Переменные»).Есть ли способ отфильтровать их программно?Например, я хочу, чтобы все экземпляры класса FieldInstruction, где

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

оценивается как true.

Поскольку я пытаюсь отладить код, который уже должен быть перечисляемвсе экземпляры, просто создание моего собственного кода, обход древовидной структуры, в которой существуют классы, как бы противоречит цели.Я бы очень хотел сделать эту фильтрацию через окна Display или Expressions.

1 Ответ

2 голосов
/ 11 августа 2010

Я закончил тем, что создал довольно хакерский класс "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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...