Получить идентификатор экземпляра, как это делает отладчик Eclipse - PullRequest
2 голосов
/ 13 июля 2020

Eclipse имеет удобную функцию, когда вы приостанавливаете работу отладчика, которая показывает идентификатор для каждого экземпляра. Они кажутся последовательными и зависят от того, когда был выделен экземпляр:

Пример идентификаторов в сеансе отладки

Я нахожу их чрезвычайно полезными, когда вникаю в серьезную проблему, поскольку обычно это небольшие целые числа, которые намного легче запомнить, чем полные коды ha sh или другие внутренний идентификатор. Они очень быстро проверяют, "это все еще тот объект, который я думаю?" когда вы проходите сложные и глубокие вызовы.

Эти идентификаторы распределения отслеживаются самим jvm, или это что-то, что Eclipse предоставляет через какой-то неизвестный механизм?

Есть ли способ получить их из кода, чтобы я мог временно помещать их в сообщения журнала во время отладки?

Я действительно не хочу добавлять поле идентификатора к каждому объекту, есть много веских причин, почему это плохая идея .

1 Ответ

4 голосов
/ 14 июля 2020

Эти идентификаторы распределения отслеживаются самим jvm, или это что-то, что Eclipse предоставляет через какой-то неизвестный механизм?

Идентификаторы объектов генерируются агентом JDWP . Агент JDWP - это библиотека, которая предоставляет возможности отладки JVM для внешних Java отладчиков (например, Eclipse IDE) через протокол JDWP .

Агент обычно запускается с JVM из командной строки. option -agentlib:jdwp= или -Xrunjdwp.

Они кажутся последовательными и зависят от того, когда был выделен экземпляр

Идентификаторы генерируются по запросу, когда агенту нужно отправить ссылку на объект отладчику. Они не связаны со временем создания объекта или чем-то еще. Java объектам изначально не присвоены идентификаторы.

Есть ли способ получить к ним доступ из кода

Как я уже сказал выше, идентификаторы объектов не существуют до тех пор, пока агент обменивается ссылками на объекты с отладчиком.

Но вы можете сгенерировать свои собственные идентификаторы для объектов, используя IdentityHashMap или подобное. Вот простейший способ создания таких идентификаторов:

private static final Map<Object, Long> map = new IdentityHashMap<>();

private static long nextId;

public static long getId(Object o) {
    synchronized (map) {
        Long id = map.get(o);
        if (id == null) {
            map.put(o, id = ++nextId);
        }
        return id;
    }
}

Конечно, эта реализация не идеальна, так как она использует глобальную блокировку и сохраняет объекты навсегда. Лучшим решением будет своего рода WeakIdentityConcurrentMap .

Фактически, именно так агент JDWP генерирует идентификаторы объектов. Он хранит внутреннюю таблицу ha sh, которая сопоставляет объект с последовательно вставляемым целым числом и использует подсчет ссылок для удаления. См. commonRef. c

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...