Ich schreibe eine Anwendung im Zusammenhang mit einer JVM-Instanz und schaue mir Open Source an, um zu sehen, wie es einige Probleme lösen kann. Die JConsole von JDK7 sammelt laufende VMs auf zwei Arten (siehe GPL2 lizenzierter Quellcode in jdk/src/share/classes/sun/tools/jconsole/LocalVirtualMachine.java
). Die erste ist jvmstat Weg, Code wie dieser:
private static void getMonitoredVMs(Map<Integer, LocalVirtualMachine> map) {
MonitoredHost host;
Set vms;
try {
host = MonitoredHost.getMonitoredHost(new HostIdentifier((String)null));
vms = host.activeVms();
} catch (java.net.URISyntaxException sx) {
throw new InternalError(sx.getMessage());
} catch (MonitorException mx) {
throw new InternalError(mx.getMessage());
}
for (Object vmid: vms) {
if (vmid instanceof Integer) {
int pid = ((Integer) vmid).intValue();
String name = vmid.toString(); // default to pid if name not available
boolean attachable = false;
String address = null;
try {
MonitoredVm mvm = host.getMonitoredVm(new VmIdentifier(name));
// use the command line as the display name
name = MonitoredVmUtil.commandLine(mvm);
attachable = MonitoredVmUtil.isAttachable(mvm);
address = ConnectorAddressLink.importFrom(pid);
mvm.detach();
} catch (Exception x) {
// ignore
}
map.put((Integer) vmid,
new LocalVirtualMachine(pid, name, attachable, address));
}
}
}
Der zweite Weg ist die Befestigung und sieht so aus:
private static void getAttachableVMs(Map<Integer, LocalVirtualMachine> map) {
List<VirtualMachineDescriptor> vms = VirtualMachine.list();
for (VirtualMachineDescriptor vmd : vms) {
try {
Integer vmid = Integer.valueOf(vmd.id());
if (!map.containsKey(vmid)) {
boolean attachable = false;
String address = null;
try {
VirtualMachine vm = VirtualMachine.attach(vmd);
attachable = true;
Properties agentProps = vm.getAgentProperties();
address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
vm.detach();
} catch (AttachNotSupportedException x) {
// not attachable
} catch (IOException x) {
// ignore
}
map.put(vmid, new LocalVirtualMachine(vmid.intValue(),
vmd.displayName(),
attachable,
address));
}
} catch (NumberFormatException e) {
// do not support vmid different than pid
}
}
}
Meine Frage: Warum werden zwei verschiedene Tools zum Abrufen der Liste virtueller Maschinen verwendet? Ich weiß, dass man über die Attach-Api nur VMs auflisten kann, die mit der gleichen JRE laufen, aber jvmstat kann eine Liste aller VMs liefern, die mit beliebigen JRE-Versionen laufen. Ich habe nur JRE/JDK 7 32 und 64-bit getestet, weil diese und neuere Versionen mein Ziel sind, leider nur unter Windows. Reicht es nicht aus, nur jvmstat zu verwenden? Gibt es einen Fall, in dem eine VM durch die Attach-Api sichtbar ist, aber jvmstat sie nicht sehen kann?