有没有办法以编程方式在当前的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>
答案 0 :(得分:3)
您可以将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
答案 1 :(得分:0)
可能不是没有通过JVM Tool Interface (JVM TI)或篡改Object的实现(这是一项棘手的业务)。
这篇文章可能很有用:Creating a Debugging and Profiling Agent with JVMTI。
答案 2 :(得分:0)
如果您指的是最常用的顶级类,您可以在构造函数周围定义切入点并跟踪每种类型的初始化。你可以使用AspectJ。
答案 3 :(得分:0)
我认为你不能在同一个JVM中做到这一点,因为你需要遍历对象堆,并且最终可能会进入无限循环。出于好奇,我尝试使用jmap
针对同一个JVM生成Runtime.exec
,甚至针对不同的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);
}
答案 4 :(得分: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)
...