Is it possible to use a Java agent to get the number of instances of any Java class? For example if we have
class Apple {
...
}
The Java agent will return how many Apple
instances are there in the JVM.
If it's not possible with a Java agent, is it possible to do it in another cross-platform manner - and without debug mode enabled (so JVMTI and JDI excluded)?
In order to count instances, you'll need to walk through the entire heap. Java Agents don't have such functionality. Basically, all they have is Instrumentation API.
The task is simple to do with JVM TI. There is IterateOverInstancesOfClass function which does almost what you want. JVM TI is not cross-platform, but you may create a JAR with dynamic libraries for the main supported platforms, and load the suitable one in runtime. That's how JNA works, for example.
The closest pure Java alternative is HotSpot diagnostic command to get a class histogram:
String histogram = (String) ManagementFactory.getPlatformMBeanServer().invoke(
new ObjectName("com.sun.management:type=DiagnosticCommand"),
"gcClassHistogram",
new Object[]{null},
new String[]{"[Ljava.lang.String;"});
Among other things, it returns the number of instances of each 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
...
This is not a standard API though.