2009-12-22 62 views
16

目前我正在研究Java代理来组装内存统计信息。在instrumentation API的帮助下,我可以掌握这些类(并操作它们)。用普通的Java,我可以估计每个对象使用的资源。到现在为止还挺好。是否有一种简单的方法来获取Java中特定类的所有对象实例

我现在面临的问题是“如何获得特定类的每个对象实例”。我可以通过字节码操作来获取对象实例,但我希望还有另一个我不知道的API,它可以帮助我在没有这样一个相当沉重的入侵步骤的情况下完成我的目标。最后,应将性能影响降至最低。有任何想法吗?

回答

20

调试器在Eclipse可以show you all the instances of a class,所以我环顾四周Eclipse的来源。 Eclipse使用Java Debug Wire Protocol,它允许您(自Java 6以来)查找所请求的类的所有实例。如果您想要沿着这条路走下去,可以拿一份Eclipse源文件并查看instances方法org.eclipse.jdi.internal.ReferenceTypeImpl

更简单的方法是使用Java Debug Interface。请注意0​​方法。

我还没有想出如何使用JDI连接到正在运行的进程以及如何获取ReferenceType的实例。 JDK包含几个examples,所以我相信它是可行的。

0

从我之前发表的文章中得知,没有办法获得Java中所有类实例的列表。反射API做一些整洁的事情,但不是这个特定的事情。

你可以做的最好的事情是持有指向所有对象的指针,但这似乎是淫秽的,并不适用于其他人的程序。不理想呃?

+4

如果使用WeakReferences(http://java.sun.com/javase/6/docs/api/java/lang/ref/WeakReference.html)执行操作,保持指针实际上并不是那种猥亵。 – 2009-12-22 15:37:41

4

当我读到这个时,我一直在想,有一些方法可以获得这种信息,因为java profiler存在。也许这会帮助: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. 
+2

JVMPI已被JVMTI取代(http://java.sun.com/javase/6/docs/technotes/guides/jvmti/index。html) - 但实际上读取OP的+1,并使用工具接口 – kdgregory 2009-12-22 15:49:22

+0

+1进行响应,以使其更加相关:) – danben 2009-12-22 15:50:49

1

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

可以编写获得JVMTI指针一些本机代码,然后使用它来 遍历一个给定的类的所有实例,如图上面的链接。 你可以从你的Java程序中调用这个本地代码。正如Eli所指出的那样,Java 6以上版本中提供了一个称为Java调试接口的高级包装器,它允许您从Java本身进行这种调用,而无需使用本机代码。

希望这有助于

拉姆

1

我不知道如果你正在尝试做可能会使用BTrace实现呢?

相关问题