You can use the JDI interface to count objects. It comes with the JDK. To use it include the tools.jar
file in your class path. I've written a code example below using JUnit 4.
public class MarsRover {
public String toString() {
return "I'm a cool robot";
}
}
private static VirtualMachine vm;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
VirtualMachineManager vmm = Bootstrap.virtualMachineManager();
List<AttachingConnector> acl = vmm.attachingConnectors();
for(AttachingConnector ac: acl) {
if(ac.transport().name().equals("dt_socket")) {
Map<String, Connector.Argument> arg = ac.defaultArguments();
arg.get("port").setValue("3001");
arg.get("timeout").setValue("30");
vm = ac.attach(arg);
}
}
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
vm.dispose();
}
public static long[] getObjectCount(Class<?> c) {
return vm.instanceCounts(vm.classesByName(c.getName()));
}
@Test
public void test() {
final long[] objectCount;
final List<MarsRover> mrArray = Arrays.asList(new MarsRover(), new MarsRover(), new MarsRover());
objectCount = getObjectCount(MarsRover.class);
assertThat(objectCount.length, is(1));
assertThat(objectCount[0], is(3L));
}
To run this code you will need to add the following options to your Java call:
-Xrunjdwp:transport=dt_socket,address=3001,server=y,suspend=n
This BeyoundJava article gave me the basic idea for this solution.