3

私はいくつかのJVMインスタンス関連のアプリケーションを作成していて、それがいくつかの問題をどのように解決するかを確認するためにオープンソースを調べています。JDK7のJConsoleは、実行中のVMを2つの方法で収集します(のGPL2によってライセンスされたソースを参照してくださいjdk/src/share/classes/sun/tools/jconsole/LocalVirtualMachine.java)。1つ目はjvmstatの方法で、次のようなコードです。

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));
        }
    }
}

2つ目はアタッチ方法で、次のようになります。

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
        }
    }
}

私の質問:仮想マシンリストを取得するために2つの異なるツールを使用するのはなぜですか?attach apiを使用すると、この同じJREで実行されているVMのみを一覧表示できますが、jvmstatでは、任意のJREバージョンで実行されているすべてのVMの一覧を表示できます。JRE / JDK 7 32ビットと64ビットをテストしたのは、それら以降がターゲットであるためです。残念ながら、Windowsのみでテストしました。jvmstatだけを使用するのに十分ではありませんか?一部のVMがアタッチAPIで表示されているのに、jvmstatで表示されない場合はありますか?

4

1 に答える 1

1

通常、すべてのjvmプロセスを検索する場合、attachapiはjvmstatと同じです。しかし、いくつかのカスタマイズされた状況では、それは異なります。そして、その違いはcom.sun.tools.attach.spi.AttachProviderです。

たとえば、Windowsプラットフォームでは、jvmstatはディレクトリ%TEMP%/ hsperfdata_caoxudong(Linuxでは/ tmp / hsperfdata_caoxudong)内のすべてのファイルを一覧表示することによってJavaプロセスを検索します。そして、attach apiは、AttachProviderインスタンスによってJavaプロセスを検索します。jdkは、OSプラットフォームに依存するデフォルトのAttachProvider実装を提供します。Windowsプラットフォームでは、実装はsun.tools.attach.WindowsAttachProviderです。そのlistVirtualMachinesメソッドで、isTempPathSecureメソッドがfalseを返す場合、すべてのプロセスを繰り返し、ライブラリ「jvm.dll」をロードしたすべてのプロセスを検索します。独自のAttachProvider実装をインストールして、独自の方法でJavaプロセスを見つけることができ、その結果はjvmstatとは異なる場合があります。AttachProviderのインストールはこちらです。

于 2012-07-24T02:22:48.883 に答える