2009-12-22 60 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實現呢?

相關問題