使用 Java 代理获取给定 Java class 的实例数?
Get number of instances of a given Java class using a Java agent?
是否可以使用 Java 代理来获取任何 Java class 的实例数?
例如,如果我们有
class Apple {
...
}
Java 代理将 return JVM 中有多少 Apple
个实例。
如果使用 Java 代理不可行,是否可以以另一种跨平台方式进行 - 并且不启用调试模式(因此排除 JVMTI 和 JDI)?
为了对实例进行计数,您需要遍历整个堆。 Java代理没有这样的功能。基本上,他们只有 Instrumentation API.
使用 JVM TI 可以轻松完成此任务。 IterateOverInstancesOfClass 函数几乎可以满足您的需求。 JVM TI 不是跨平台的,但你可以为主要支持的平台创建一个带有动态库的 JAR,并在运行时加载合适的。例如,这就是 JNA 的工作原理。
最接近的纯 Java 替代方法是获取 class 直方图的 HotSpot 诊断命令:
String histogram = (String) ManagementFactory.getPlatformMBeanServer().invoke(
new ObjectName("com.sun.management:type=DiagnosticCommand"),
"gcClassHistogram",
new Object[]{null},
new String[]{"[Ljava.lang.String;"});
除其他外,它 returns 每个 class 的实例数:
num #instances #bytes class name
----------------------------------------------
1: 3269 265080 [C
2: 1052 119160 java.lang.Class
3: 156 92456 [B
4: 3247 77928 java.lang.String
5: 1150 54104 [Ljava.lang.Object;
6: 579 50952 java.lang.reflect.Method
7: 292 21024 java.lang.reflect.Field
8: 395 12640 java.util.HashMap$Node
...
虽然这不是标准 API。
是否可以使用 Java 代理来获取任何 Java class 的实例数? 例如,如果我们有
class Apple {
...
}
Java 代理将 return JVM 中有多少 Apple
个实例。
如果使用 Java 代理不可行,是否可以以另一种跨平台方式进行 - 并且不启用调试模式(因此排除 JVMTI 和 JDI)?
为了对实例进行计数,您需要遍历整个堆。 Java代理没有这样的功能。基本上,他们只有 Instrumentation API.
使用 JVM TI 可以轻松完成此任务。 IterateOverInstancesOfClass 函数几乎可以满足您的需求。 JVM TI 不是跨平台的,但你可以为主要支持的平台创建一个带有动态库的 JAR,并在运行时加载合适的。例如,这就是 JNA 的工作原理。
最接近的纯 Java 替代方法是获取 class 直方图的 HotSpot 诊断命令:
String histogram = (String) ManagementFactory.getPlatformMBeanServer().invoke(
new ObjectName("com.sun.management:type=DiagnosticCommand"),
"gcClassHistogram",
new Object[]{null},
new String[]{"[Ljava.lang.String;"});
除其他外,它 returns 每个 class 的实例数:
num #instances #bytes class name
----------------------------------------------
1: 3269 265080 [C
2: 1052 119160 java.lang.Class
3: 156 92456 [B
4: 3247 77928 java.lang.String
5: 1150 54104 [Ljava.lang.Object;
6: 579 50952 java.lang.reflect.Method
7: 292 21024 java.lang.reflect.Field
8: 395 12640 java.util.HashMap$Node
...
虽然这不是标准 API。