List of running JVMs on the localhost

后端 未结 8 1350
慢半拍i
慢半拍i 2020-12-24 15:57

How to get in Java 6+ the list of running JVMs on the localhost and their specs (i.e. Java version, running threads, etc.)?

Does the Java API provide such features?

8条回答
  •  天命终不由人
    2020-12-24 16:22

    If you need just list of running JVMs with PIDs this works for me:

    package my.code.z025.util;
    
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Set;
    
    import sun.jvmstat.monitor.HostIdentifier;
    import sun.jvmstat.monitor.MonitorException;
    import sun.jvmstat.monitor.MonitoredHost;
    import sun.jvmstat.monitor.MonitoredVm;
    import sun.jvmstat.monitor.MonitoredVmUtil;
    import sun.jvmstat.monitor.VmIdentifier;
    
    /**
     * Get list of all local active JVMs
     */
    public class ActiveJavaVirtualMachineExplorer {
    
        /**
         * Represents successfully captured active java virtual machine 
         */
        public static class ActiveVm {
            private int pid;
            private String name;
                ... shortened ...
        }
    
        /**
         * Represents unsuccessfully captured active java virtual machine, a failure.
         * Keep cause exception. 
         */
        public static class FailedActiveVm extends ActiveVm {
            private Exception cause;
            ... shortened ...
        }
    
        /**
         * Get list of all local active JVMs.
         * 

    * Returns something like: * ActiveVm [pid=7992, name=my.code.z025.util.launch.RunHttpServer] * ActiveVm [pid=6972, name=] * ActiveVm [pid=8188, name=my.code.z025.util.launch.RunCodeServer] * ActiveVm [pid=4532, name=org.eclipse.jdt.internal.junit.runner.RemoteTestRunner] * The pid=6972 must be Eclipse. So this approach is not water tight. */ public static List getActiveLocalVms() { List result = new LinkedList(); MonitoredHost monitoredHost; Set activeVmPids; try { monitoredHost = MonitoredHost.getMonitoredHost(new HostIdentifier((String) null)); activeVmPids = monitoredHost.activeVms(); for (Integer vmPid : activeVmPids) { try { MonitoredVm mvm = monitoredHost.getMonitoredVm(new VmIdentifier(vmPid.toString())); result.add(new ActiveVm(vmPid.intValue(), MonitoredVmUtil.mainClass(mvm, true))); mvm.detach(); } catch (Exception e) { result.add(new FailedActiveVm(vmPid.intValue(), e)); } } return result; } catch (java.net.URISyntaxException e) { throw new InternalError(e.getMessage()); } catch (MonitorException e) { throw new InternalError(e.getMessage()); } } }

    Application does not have to be run with any special command line parameters to be detectable like this. No need to activate JMX.

    Not all JVM apps play well though. For Eclipse I see only PID, but not class name or command line.

    You have to add tool.jar to your classpath, it contains packages sun.jvmstat.*. The tool.jar is part of JDK. With some variant of JDK/OS it is on classpath by default, with some you have to add it. Doing so with Maven dependencies is a bit tricky, systemPath is required.

    If you want more then just list, check the link from Paŭlo Ebermann - Monitoring and Management Using the JMX API.

    VirtualMachine vm = VirtualMachine.attach(pid);
    

    Where the PID you get from the list. Then insert your Agent to (unsuspected) Java (or any JVM) application.

    vm.loadAgent(agentJarLibraryFullPath);
    

    Then communicate with your agent via JMXConnector. Your agent can gather all the statistics for you. I have not personally tried that. You can even instrument (modify) run time code this way. Profilers use that.

提交回复
热议问题