2010-09-21 9 views
7

est-il possible d'imprimer par programmation les classes N les plus utilisées sur l'application Java actuelle?L'impression de l'histogramme de classe par programme

sortie

exemple: 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

Netbeans profiler le fait bien, Netbeans est écrit en Java, donc ... Oui, il y a un moyen =) Ici, vous allez! – BenoitParis

+0

Que voulez-vous dire par "top utilisé"? Les classes avec le plus grand nombre d'instances à un moment donné ou au total sur la durée de vie de l'application? Ou peut-être que vous voulez dire les classes dont les méthodes sont invoquées le plus? (mesure basée sur le temps ou mesure du nombre d'invocations) –

+0

Qu'est-ce que [J? [I est un tableau d'entier, mais J? –

Répondre

0

Probablement pas sans passer par JVM Tool Interface (JVM TI) ou l'altération de la mise en œuvre de l'objet (qui est une affaire délicate).

Cet article est peut-être utile: Creating a Debugging and Profiling Agent with JVMTI.

+0

je vous remercie pour vos commentaires. Je pense que l'utilisation de source jmap peut être une bonne option .. il est risqué sur l'environnement en direct .. http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules-sun/tools/sun/tools /jmap/JMap.java.htm – Trustin

0

Si vous voulez dire par dessus utilisé, les classes les plus initialisées, vous pouvez définir un point-point autour des constructeurs et garder une trace des initialisations pour chaque type. Vous pouvez utiliser AspectJ d'ailleurs.

+0

Je veux faire la même chose avec jmap -histo [: live] pid sans changer notre programme. parce que le système est vivant. Je ne veux pas ajouter de frais généraux en ajoutant de telles coupures de points. Aussi, je ne peux pas faire confiance à la méthode finilizer pour diminuer le nombre. – Trustin

+0

donc vous voulez voir le nombre d'instances à un point donné, je pensais que vous vouliez voir le nombre total d'instances créées. Ensuite, je pense que ce dont vous avez besoin est une API de profilage. Vous pouvez vérifier le paquet java.lang.management mais je ne suis pas sûr qu'il soit possible d'obtenir le nombre d'instances – hakan

0

Je ne pense pas que vous puissiez le faire dans la même JVM car vous devez traverser le tas d'objets, et vous pourriez finir dans une boucle infinie. Juste par curiosité, j'ai essayé de pondre jmap en utilisant Runtime.exec contre la même JVM et même contre une JVM différente et il se bloque juste?

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

Vous pouvez lancer jmap dans le cadre de votre script d'emballage java et l'exécuter en continu dans une boucle:

Par exemple, si vous êtes sous Unix, vous pourriez faire quelque chose comme:

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