2009-12-22 9 views
16

Attualmente sto lavorando su un agente Java per assemblare le statistiche della memoria. Con l'aiuto di instrumentation API posso ottenere una sospensione delle classi (e manipolarle). Con Java semplice posso ottenere una stima delle risorse utilizzate per ciascun oggetto. Fin qui tutto bene.Esiste un modo semplice per ottenere tutte le istanze di oggetti di una classe specifica in Java

La domanda che sto affrontando adesso è "come ottenere una sospensione di ogni istanza di Object di una classe specifica". Posso eseguire la manipolazione del codice byte per ottenere una sospensione dell'istanza dell'oggetto, ma speravo ci fosse un'altra API di cui non sono a conoscenza, aiutandomi a raggiungere il mio obiettivo senza un passaggio invadente piuttosto pesante. Alla fine, l'impatto sulle prestazioni dovrebbe essere ridotto al minimo. Qualche idea?

risposta

20

Il debugger in Eclipse può show you all the instances of a class, così mi sono guardato intorno fonti di Eclipse. Eclipse utilizza lo Java Debug Wire Protocol, che consente (a partire da Java 6) di cercare tutte le istanze della classe richiesta. Se vuoi seguire questo percorso, prendi una copia delle fonti di Eclipse e controlla il metodo instances di org.eclipse.jdi.internal.ReferenceTypeImpl.

Un modo più semplice è utilizzare Java Debug Interface. Nota il metodo ReferenceType.instances.

Non ho ancora capito come utilizzare JDI per connettersi a un processo in esecuzione e come ottenere un'istanza di ReferenceType. Il JDK contiene diversi examples, quindi sono sicuro che sia fattibile.

0

Da quanto mi è stato detto nei post precedenti, non c'è modo di ottenere un elenco di tutte le istanze di una classe in Java. La reflection API fa alcune cose pulite ma non questa cosa specifica.

La cosa migliore che puoi fare è tenere puntatori a tutti gli oggetti, ma ciò sembra osceno e non funziona sui programmi di altre persone. Non è l'ideale eh?

+4

I puntatori in attesa non sono effettivamente così osceni se lo fai con WeakReferences (http://java.sun.com/javase/6/docs/api/java/lang/ref/WeakReference.html). –

4

Quando ho letto questo ho pensato che ci deve essere un modo per ottenere questo tipo di informazioni, dal momento che esistono profilatori java. Forse questo aiuterà: http://java.sun.com/j2se/1.4.2/docs/guide/jvmpi/jvmpi.html. Descrive l'interfaccia tra la JVM e un agente di profilazione. Ma se davvero stavi cercando di scrivere questo in Java potresti essere sfortunato.

In particolare, controllare questa funzione:

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 è stato sostituito da JVMTI (http://java.sun.com/javase/6/docs/technotes/guides/jvmti/index.html) - ma +1 per leggere effettivamente l'OP e rispondere con l'interfaccia dello strumento – kdgregory

+0

+1 per renderlo più rilevante :) – danben

1

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

È possibile scrivere del codice nativo che ottiene il puntatore JVMTI e poi lo usa per iterare su tutte le istanze di una data classe, come indicato nel link qui sopra. È possibile chiamare questo codice nativo dal proprio programma Java. Tuttavia, come fa notare Eli, esiste un wrapper di alto livello per questo chiamato Java Debug Interface disponibile da Java 6 in poi, che consente di effettuare chiamate di questo tipo da Java senza dover utilizzare il codice nativo.

speranza che questo aiuta

Ram

1

Mi chiedo se ciò che si sta cercando di fare potrebbe essere realizzato utilizzando BTrace?

Problemi correlati