我正在寫一些JVM實例相關的應用程序,並看着開源,看看它是如何解決一些問題。 JDK7的JConsole以兩種方式收集正在運行的VM(請查看jdk/src/share/classes/sun/tools/jconsole/LocalVirtualMachine.java
中的GPL2許可的源代碼)。首先是jvmstat的方式,這樣的代碼:爲什麼JDK的JConsole尋找使用jvmstat和attach api的虛擬機?
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));
}
}
}
二是重視的方式,看起來是這樣的:
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
}
}
}
我的問題:爲什麼它使用兩種不同的工具來獲取虛擬機列表?我知道通過附加API可以列出僅由同一個JRE運行的VM,但是jvmstat可以爲您提供使用任何JRE版本運行的所有VM的列表。我已經測試過JRE/JDK 7 32和64位,只是因爲他們和更新是我的目標,不幸的是只在Windows上。僅僅使用jvmstat是不夠的?是否有任何情況下,通過attach api可以看到某個VM,但jvmstat無法看到它?