Repository navigation
jcmd jps
wangkaiwu edited this page May 29, 2022
·
4 revisions
下面的内容涉及到了 MonitoredVM源码解析 的内容
$ jps -l
65416 jdk.jcmd/sun.tools.jps.Jps位于 openJdk 的 jdk.jcmd 包中
package sun.tools.jps;
public class Jps {
private static Arguments arguments;
public static void main(String[] args) {
// 组装参数
arguments = new Arguments(args);
HostIdentifier hostId = arguments.hostId();
MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(hostId);
Set<Integer> jvms = monitoredHost.activeVms();
for (Integer jvm : jvms) {
StringBuilder output = new StringBuilder();
int lvmid = jvm;
output.append(String.valueOf(lvmid));
if (arguments.isQuiet()) {
System.out.println(output);
continue;
}
MonitoredVm vm = null;
String vmidString = "//" + lvmid + "?mode=r";
VmIdentifier id = new VmIdentifier(vmidString);
vm = monitoredHost.getMonitoredVm(id, 0);
output.append(' ').append(MonitoredVmUtil.mainClass(vm,
arguments.showLongPaths()));
if (arguments.showMainArgs()) {
String mainArgs = MonitoredVmUtil.mainArgs(vm);
output.append(' ').append(mainArgs);
}
if (arguments.showVmArgs()) {
String jvmArgs = MonitoredVmUtil.jvmArgs(vm);
output.append(' ')
.append(
// multi-line args are permitted
jvmArgs.replace("\n", "\\n").replace("\r", "\\r")
);
}
if (arguments.showVmFlags()) {
String jvmFlags = MonitoredVmUtil.jvmFlags(vm);
output.append(' ').append(jvmFlags);
}
monitoredHost.detach(vm);
System.out.println(output);
}
}
}public class Arguments {
private boolean help;
private boolean quiet;
private boolean longPaths;
private boolean vmArgs;
private boolean vmFlags;
private boolean mainArgs;
private String hostname;
private HostIdentifier hostId;
public Arguments(String[] args) throws IllegalArgumentException {
int argc = 0;
for (argc = 0; (argc < args.length) && (args[argc].startsWith("-"));
argc++) {
String arg = args[argc];
// -q 的意思就是 只输出进程ID
if (arg.compareTo("-q") == 0) {
quiet = true;
} else if (arg.startsWith("-")) {
for (int j = 1; j < arg.length(); j++) {
switch (arg.charAt(j)) {
case 'm':
mainArgs = true;
break;
case 'l':
longPaths = true;
break;
case 'v':
vmArgs = true;
break;
case 'V':
vmFlags = true;
break;
}
}
}
}
switch (args.length - argc) {
case 0:
// hostname 会当做 //localhost
hostname = null;
break;
case 1:
// 最后一个参数会当做 hostname, 格式为 //
hostname = args[args.length - 1];
break;
}
hostId = new HostIdentifier(hostname);
}
}ceragon@ceragon-ThinkPad-T440p:/tmp/hsperfdata_ceragon$ ls
12268 386347
ceragon@ceragon-ThinkPad-T440p:/tmp/hsperfdata_ceragon$ jps -l
405830 jdk.jcmd/sun.tools.jps.Jps
12268
386347 com.intellij.idea.Mainpublic abstract class MonitoredHost {
private static ServiceLoader<MonitoredHostService> monitoredHostServiceLoader =
ServiceLoader.load(MonitoredHostService.class, MonitoredHostService.class.getClassLoader());
public static MonitoredHost getMonitoredHost(HostIdentifier hostId) throws MonitorException {
for (MonitoredHostService mhs : monitoredHostServiceLoader) {
if (mhs.getScheme().equals(hostId.getScheme())) {
mh = mhs.getMonitoredHost(hostId);
}
}
}
}public final class MonitoredHostLocalService implements MonitoredHostService {
@Override
public MonitoredHost getMonitoredHost(HostIdentifier hostId) throws MonitorException {
return new MonitoredHostProvider(hostId);
}
}public class MonitoredHostProvider extends MonitoredHost {
private LocalVmManager vmManager;
public MonitoredHostProvider(HostIdentifier hostId) {
this.vmManager = new LocalVmManager();
}
public Set<Integer> activeVms() {
return vmManager.activeVms();
}
}public class LocalVmManager {
private List<String> tmpdirs;
public LocalVmManager() {
this(null);
}
public LocalVmManager(String user) {
this.userName = user;
if (userName == null) {
tmpdirs = PerfDataFile.getTempDirectories(null, 0);
}
}
}public class PerfDataFile {
private static final PlatformSupport platSupport = PlatformSupport.getInstance();
public static List<String> getTempDirectories(String userName, int vmid) {
List<String> list = platSupport.getTemporaryDirectories(vmid);
if (userName == null) {
return list;
}
}
}public class PlatformSupport {
private static final String tmpDirName;
static {
// 从上面的例子来看,linux 下 tmpdir = /tmp/hsperfdata_ceragon
String tmpdir = VMSupport.getVMTemporaryDirectory();
tmpDirName = tmpdir;
}
public List<String> getTemporaryDirectories(int vmid) {
return List.of(tmpDirName);
}
}ceragon@ceragon-ThinkPad-T440p:/tmp/hsperfdata_ceragon$ ls
12268 386347public class MonitoredHostProvider extends MonitoredHost {
private LocalVmManager vmManager;
public Set<Integer> activeVms() {
return vmManager.activeVms();
}
}public class LocalVmManager {
private FilenameFilter fileFilter;
private Pattern filePattern;
private Matcher fileMatcher;
// 上面已经分析了 临时路径的获取方法
private List<String> tmpdirs;
public LocalVmManager() {
this(null);
}
public LocalVmManager(String user) {
// fileNamePattern = "^[0-9]+$"
filePattern = Pattern.compile(PerfDataFile.fileNamePattern);
fileMatcher = filePattern.matcher("");
fileFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
fileMatcher.reset(name);
return fileMatcher.matches();
}
};
}
public synchronized Set<Integer> activeVms() {
Set<Integer> jvmSet = new HashSet<>();
for (String dir : tmpdirs) {
File tmpdir = new File(dir);
if (userName == null) {
// 找出当前用户可用的目录
File[] dirs = tmpdir.listFiles(userFilter);
for (int i = 0; i < dirs.length; i++) {
// 目录中的所有文件
File[] files = dirs[i].listFiles(fileFilter);
for (int j = 0; j < files.length; j++) {
if (files[j].isFile() && files[j].canRead()) {
int vmid = PerfDataFile.getLocalVmId(files[j]);
jvmSet.add(vmid);
}
}
}
}
}
return jvmSet;
}
}public class PerfDataFile {
private static final PlatformSupport platSupport = PlatformSupport.getInstance();
public static int getLocalVmId(File file) {
return (platSupport.getLocalVmId(file));
}
}public class PlatformSupportImpl extends PlatformSupport {
public int getLocalVmId(File file) throws NumberFormatException {
String p = file.getAbsolutePath();
String s[] = p.split("\\/");
if (s.length == 7 && s[1].equals("proc")) {
int hostpid = Integer.parseInt(s[2]);
int nspid = Integer.parseInt(s[6]);
if (nspid == hostpid || nspid == getNamespaceVmId(hostpid)) {
return hostpid;
}
return -1;
}
return Integer.parseInt(file.getName());
}
}public class MonitoredVmUtil {
public static String mainClass(MonitoredVm vm, boolean fullPath) throws MonitorException {
String cmdLine = commandLine(vm);
int firstSpace = cmdLine.indexOf(' ');
if (firstSpace > 0) {
cmdLine = cmdLine.substring(0, firstSpace);
}
if (fullPath) {
return cmdLine;
}
}
public static String commandLine(MonitoredVm vm) throws MonitorException {
StringMonitor cmd = (StringMonitor) vm.findByName("sun.rt.javaCommand");
return (cmd == null) ? "Unknown" : cmd.stringValue();
}
}public class MonitoredVmUtil {
public static String mainArgs(MonitoredVm vm) throws MonitorException {
String commandLine = commandLine(vm);
int firstSpace = commandLine.indexOf(' ');
return commandLine.substring(firstSpace + 1);
}
public static String commandLine(MonitoredVm vm) throws MonitorException {
StringMonitor cmd = (StringMonitor) vm.findByName("sun.rt.javaCommand");
return (cmd == null) ? "Unknown" : cmd.stringValue();
}
}public class MonitoredVmUtil {
public static String jvmArgs(MonitoredVm vm) throws MonitorException {
StringMonitor jvmArgs = (StringMonitor) vm.findByName("java.rt.vmArgs");
return (jvmArgs == null) ? "Unknown" : jvmArgs.stringValue();
}
}public class MonitoredVmUtil {
public static String jvmFlags(MonitoredVm vm) throws MonitorException {
StringMonitor jvmFlags =
(StringMonitor) vm.findByName("java.rt.vmFlags");
return (jvmFlags == null) ? "Unknown" : jvmFlags.stringValue();
}
}void StatSampler::create_misc_perfdata() {
PerfDataManager::create_string_constant(JAVA_RT, "vmFlags",
Arguments::jvm_flags(), CHECK);
PerfDataManager::create_string_constant(JAVA_RT, "vmArgs",
Arguments::jvm_args(), CHECK);
PerfDataManager::create_string_constant(SUN_RT, "javaCommand",
Arguments::java_command(), CHECK);
}