Есть ли простой способ получения всех экземпляров объекта определенного класса в Java - PullRequest
17 голосов
/ 22 декабря 2009

В настоящее время я работаю над агентом Java для сбора статистики памяти. С помощью API инструментария я могу овладеть классами (и манипулировать ими). С простой Java я могу получить оценку ресурсов, используемых для каждого объекта. Пока все хорошо.

Вопрос, с которым я сейчас сталкиваюсь, заключается в том, «как завладеть каждым экземпляром Object определенного класса». Я могу выполнять манипулирование байтовым кодом, чтобы овладеть экземпляром объекта, но я надеялся, что есть еще один API, о котором я не знаю, который поможет мне достичь цели без такого довольно тяжелого навязчивого шага. В конце, влияние на производительность должно быть сведено к минимуму. Есть идеи?

Ответы [ 5 ]

21 голосов
/ 22 декабря 2009

Отладчик в Eclipse может показать вам все экземпляры класса , поэтому я посмотрел источники Eclipse. Eclipse использует протокол отладки Java , который позволяет вам (начиная с Java 6) искать все экземпляры запрошенного класса. Если вы хотите пойти по этому пути, возьмите копию источников Eclipse и проверьте instances метод org.eclipse.jdi.internal.ReferenceTypeImpl.

Более простой способ - использовать Java Debug Interface . Обратите внимание на метод ReferenceType.instances.

Я до сих пор не понял, как использовать JDI для подключения к работающему процессу и как получить экземпляр ReferenceType. JDK содержит несколько примеров , поэтому я уверен, что это выполнимо.

4 голосов
/ 22 декабря 2009

Когда я читал это, я думал, что должен быть НЕКОТОРЫЙ способ получить такую ​​информацию, поскольку существуют профилировщики Java. Может быть, это поможет: http://java.sun.com/j2se/1.4.2/docs/guide/jvmpi/jvmpi.html. Он описывает интерфейс между JVM и агентом профилировщика. Но если вы действительно хотите написать это на Java, вам может не повезти.

В частности, проверьте эту функцию:

jint (*EnableEvent)(jint event_type, void *arg);

    Called by the profiler agent to enable notification of a particular type of event. Apart from event_type, the profiler may also pass an argument that provides additional information specific to the given event type.

    All events are disabled when the VM starts up. Once enabled, an event stays enabled until it is explicitly disabled.

    This function returns JVMPI_NOT_AVAILABLE if event_type is JVMPI_EVENT_HEAP_DUMP, JVMPI_EVENT_MONITOR_DUMP or JVMPI_EVENT_OBJECT_DUMP. The profiler agent must use the RequestEvent function to request these events.

    Arguments:

        event_type  - type of event, JVMPI_EVENT_CLASS_LOAD etc.
        arg     - event specific argument.

    Returns:

        JVMPI_SUCCESS   enable succeeded.
        JVMPI_FAIL  enable failed.
        JVMPI_NOT_AVAILABLE     support for enabling the given event_type is not available. 
1 голос
/ 23 декабря 2009

Интересно, можно ли выполнить то, что вы пытаетесь сделать, используя BTrace ?

1 голос
/ 22 декабря 2009

http://java.sun.com/j2se/1.5.0/docs/guide/jvmti/jvmti.html#IterateOverInstancesOfClass

Вы можете написать некоторый собственный код, который получает указатель JVMTI и затем использует его для переберите все экземпляры данного класса, как показано в ссылке выше. Вы можете вызвать этот нативный код из вашей Java-программы. Однако, как указывает Эли, существует высокоуровневая оболочка для этого так называемого Java Debug Interface, доступная начиная с Java 6 и выше, которая позволяет вам делать такие вызовы из самой Java, не прибегая к обходным путям с собственным кодом.

надеюсь, это поможет

Ram

0 голосов
/ 22 декабря 2009

Из того, что мне сказали в предыдущих постах, нет способа получить список всех экземпляров класса в Java. Reflection API делает некоторые полезные вещи, но не эту конкретную вещь.

Лучшее, что вы можете сделать, - это указатели на все объекты, но это кажется непристойным и не работает в программах других людей. Не идеально, а?

...