Если вам нужен просто список запущенных JVM с PID, это работает для меня:
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.
* <p>
* 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<ActiveVm> getActiveLocalVms() {
List<ActiveVm> result = new LinkedList<ActiveVm>();
MonitoredHost monitoredHost;
Set<Integer> 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());
}
}
}
Приложение не должно запускаться с какими-либо специальными параметрами командной строки, чтобы его можно было обнаружить, как это.Не нужно активировать JMX.
Не все приложения JVM работают хорошо.Для Eclipse я вижу только PID, но не имя класса или командную строку.
Вы должны добавить tool.jar
в ваш путь к классам, он содержит пакеты sun.jvmstat.*
.tool.jar
является частью JDK.В некоторых вариантах JDK / OS он по умолчанию находится в пути к классам, а в некоторых вы должны его добавить.Делать это с зависимостями Maven немного сложно, systemPath требуется.
Если вы хотите больше, чем просто список, проверьте ссылку из Paŭlo Ebermann - Мониторинг и управление с использованием JMX API .
VirtualMachine vm = VirtualMachine.attach(pid);
Где PID вы получаете из списка.Затем вставьте свой агент в (непредвиденное) приложение Java (или любую JVM).
vm.loadAgent(agentJarLibraryFullPath);
Затем свяжитесь с вашим агентом через JMXConnector.Ваш агент может собрать всю статистику для вас.Я лично не пробовал это.Таким способом вы даже можете изменить (изменить) код времени выполнения.Профилировщики используют это.