Печать гистограммы классов программно - PullRequest
8 голосов
/ 21 сентября 2010

Можно ли программно напечатать наиболее популярные N классов в текущем Java-приложении?

Пример вывода: 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>

Ответы [ 4 ]

3 голосов
/ 21 сентября 2010

Вы можете запустить jmap как часть скрипта Java-оболочки и запускать его непрерывно в цикле:

Например, если вы работаете в Unix, вы можете сделать что-то вроде:

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
0 голосов
/ 21 сентября 2010

Если вы имеете в виду под верхними используемыми классами, которые наиболее инициализированы, вы можете определить pointcut вокруг конструкторов и отслеживать инициализации для каждого типа. Вы можете использовать AspectJ в этом отношении.

0 голосов
/ 21 сентября 2010

Я не думаю, что вы можете сделать это в одной и той же JVM, потому что вам нужно пересечь кучу объектов, и вы можете оказаться в бесконечном цикле.Просто из любопытства я пытался порождать jmap, используя Runtime.exec против той же JVM и даже против другой JVM, и он просто зависает?

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);
}
0 голосов
/ 21 сентября 2010

Скорее всего, не пройдя через Интерфейс инструмента JVM (JVM TI) или вмешавшись в реализацию Object (это непростое дело).

Эта статья, возможно, полезна: Создание агента отладки и профилирования с помощью JVMTI .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...