9

現在のJavaアプリケーションで使用されている上位Nクラスをプログラムで出力する方法はありますか?

サンプル出力: 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

5 に答える 5

3

jmapJava ラッパー スクリプトの一部として開始し、ループで継続的に実行できます。

たとえば、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
于 2010-09-21T14:14:22.107 に答える
0

おそらく、JVM Tool Interface (JVM TI)を使用したり、Object の実装を改ざんしたり (これはトリッキーな作業です) しないわけではありません。

この記事はおそらく役に立ちます: JVMTI を使用したデバッグおよびプロファイリング エージェントの作成

于 2010-09-21T12:57:11.820 に答える
0

オブジェクトヒープをトラバースする必要があり、無限ループに陥る可能性があるため、同じJVM内でそれを行うことはできないと思います。好奇心から、同じ JVM に対して、さらには別の JVM に対してjmap使用してスポーンしようとしましたが、ハングするだけですか?Runtime.exec

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);
}
于 2010-09-21T13:56:39.140 に答える
0

最もよく使用される、最も初期化されるクラスを意味する場合、コンストラクターの周りにポイントカットを定義し、各タイプの初期化を追跡できます。そのためにAspectJを使用できます。

于 2010-09-21T13:28:31.760 に答える
0

Runtime#execプログラムで使用して、次のjmapように実行できます。

String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
Process p = Runtime.getRuntime().exec("jmap -histo " + pid);

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("ERR:" + line);
}
p.waitFor();

出力は次のようになります。

 num     #instances         #bytes  class name (module)
-------------------------------------------------------
   1:         55905       40469648  [B (java.base@11.0.2)
   2:          5292        7240256  [I (java.base@11.0.2)
   3:         24865         596760  java.lang.String (java.base@11.0.2)
   4:          5422         347008  java.net.URL (java.base@11.0.2)
   5:          5242         327088  [Ljava.lang.Object; (java.base@11.0.2)
...
于 2019-10-03T18:22:43.260 に答える