2010-09-21 4 views
7

Esiste un modo per stampare le classi N utilizzate in modo top nell'applicazione Java corrente in modo programmatico?Istogramma della classe di stampa a livello di programmazione

esempio di output: N = 10

num #instances #bytes class name 
-------------------------------------- 
    1:  23  4723136 [I 
    2:  19  4718928 [J 
    3:  18  4718880 [D 
    4:  73925  1774200 java.lang.String 
    5:  208  1226400 [C 
    6:  28  1205064 [B 
    7:  18  1179936 [F 
    8:  68  297040 [Ljava.lang.String; 
    9:  332  14136 [Ljava.lang.Object; 
10:  32  10240 <objArrayKlassKlass> 
+0

Il profiler Netbeans funziona bene, Netbeans è scritto in Java, quindi ... Sì, c'è un modo =) Ecco qui! – BenoitParis

+0

Cosa intendi per "top used"? Le classi con il maggior numero di istanze in un dato momento o totale per tutta la durata dell'applicazione? O forse intendi le classi i cui metodi sono maggiormente invocati? (misurazione basata sul tempo o misura del conteggio di invocazione) –

+0

Che cos'è [J? [I è una matrice di numero intero, ma J? –

risposta

0

Probabilmente non senza passare attraverso JVM Tool Interface (JVM TI) o manomissione con l'implementazione di oggetto (che è un affare complicato).

Questo articolo è forse utile: Creating a Debugging and Profiling Agent with JVMTI.

+0

grazie per i commenti. Penso che l'uso di sorgenti jmap possa essere una buona opzione .. è rischioso per l'ambiente live. Http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules-sun/tools/sun/tools /jmap/JMap.java.htm – Trustin

0

Se si intende per la parte più utilizzata, le classi inizializzate di più, è possibile definire un collegamento di punti intorno ai costruttori e tenere traccia delle inizializzazioni per ciascun tipo. Puoi usare AspectJ per quella materia.

+0

Voglio fare la stessa cosa con jmap -histo [: live] pid senza cambiare il nostro programma. perché il sistema è vivo. Non voglio aggiungere un sovraccarico aggiungendo tali punti. Inoltre non posso fidarmi del metodo del finisher per decrementare il conteggio. – Trustin

+0

quindi vuoi vedere il numero di istanze in un determinato punto, ho pensato che volevi vedere il numero totale di istanze create. Quindi penso che ciò di cui hai bisogno è un'API di profilazione. È possibile controllare il pacchetto java.lang.management ma non sono sicuro che sia possibile ottenere il conteggio delle istanze – hakan

0

Non penso che sia possibile farlo all'interno della stessa JVM perché è necessario attraversare l'heap dell'oggetto e si potrebbe finire in un ciclo infinito. Solo per curiosità, ho provato a generare spawn jmap usando Runtime.exec contro la stessa JVM e anche contro una JVM diversa e si blocca?

String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; 
//pid=2520 
System.out.println("PID: " + pid); 
Process p = Runtime.getRuntime().exec("jmap -histo " + pid); 
p.waitFor(); 
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); 
String line ; 
while((line = br.readLine())!=null){ 
    System.out.println(line); 
} 

br = new BufferedReader(new InputStreamReader(p.getErrorStream())); 
while((line = br.readLine())!=null){ 
    System.out.println(line); 
} 
3

Si potrebbe dare il via jmap come parte del vostro script wrapper Java e correre continuamente in un ciclo:

Per esempio, se siete su Unix, si potrebbe fare qualcosa di simile:

java MyMainClass ... & 

pid=$! 
while [ ! -z $pid ] 
do 
    jmap -histo $pid | head -13 
    sleep 60 

    #check pid 
    kill -0 $pid > /dev/null 2>&1 
    if [ $? -ne 0 ] 
    then 
     pid="" 
    fi 
done