我们在开发中经常会遇到这样的问题,需要把本地运行的所有某个Java应用找出来,以便于执行某种操作。所以,常见的想法是在不同的平台采用不同的实现方式:
在windows下使用netstat,linux下使用ps -ef。相对来说linux下更方便,因为ps -ef可以把详细的jvm参数和文件路径也列出来,更方便程序操作。当然,如果你使用过java的jps工具的话,感觉会更方便。
jps的usage:
usage: jps [-help]
jps [-q] [-mlvV] [<hostid>]
Definitions:
<hostid>: <hostname>[:<port>]
只需要在命令行中输入jps,就会列出当前用户的所有java进程。
当然,标准的输出只有pid和Main Class的名称。加上具体的参数 -l会列出Main Class的完整类名,再加上-v,会列出详细的jvm参数:
例如:
6544 sun.tools.jps.Jps -Dapplication.home=C:\Program Files (x86)\Java\jdk1.6.0_4
5 -Xms8m
3920 sun.tools.jconsole.JConsole -Dapplication.home=D:\Java\jdk1.6.0_10 -Djconso
le.showOutputViewer
根据完整的类名,pid可用于解决常见的问题。
但是做为一个有追求的程序员
,我们不禁要想,jps是怎么实现的呢,也是根据不同的平台使用不同的命令吗?
抱着这样的态度,我们可以查看下OpenJDK中jps的源码。看过之后会恍然大悟:原来是这样的。
***
每启动一个java应用,其会在当前用户的临时目录下创建一个临时文件,以该应用的pid命名。
public static final String dirNamePrefix = "hsperfdata_";
public static String getTempDirectory(String user) {
return tmpDirName + dirNamePrefix + user + File.separator;
}
在windows中,如果没有设置java.io.tmpdir,则会在C:\Users\UserName\AppData\Local\Temp\hsperfdata_UserName\目录下创建xxx(pid)
jps则会根据这些文件,获取本地的java进程,及具体的Main CLass 名称等。
获取代码:
Jps
try {
HostIdentifier hostId = arguments.hostId();
MonitoredHost monitoredHost =
MonitoredHost.getMonitoredHost(hostId);
// get the set active JVMs on the specified host.
Set jvms = monitoredHost.activeVms();
for (Iterator j = jvms.iterator(); j.hasNext(); /* empty */ ) {
StringBuilder output = new StringBuilder();
Throwable lastError = null;
int lvmid = ((Integer)j.next()).intValue();
output.append(String.valueOf(lvmid));
if (arguments.isQuiet()) {
System.out.println(output);
continue;
}
MonitoredVm vm = null;
String vmidString = "//" + lvmid + "?mode=r";
try {
VmIdentifier id = new VmIdentifier(vmidString);
vm = monitoredHost.getMonitoredVm(id, 0);
} catch (URISyntaxException e) {
// unexpected as vmidString is based on a validated hostid
lastError = e;
assert false;
} catch (Exception e) {
lastError = e;
} finally {
if (vm == null) {
/*
* we ignore most exceptions, as there are race
* conditions where a JVM in 'jvms' may terminate
* before we get a chance to list its information.
* Other errors, such as access and I/O exceptions
* should stop us from iterating over the complete set.
*/
output.append(" -- process information unavailable");
if (arguments.isDebug()) {
if ((lastError != null)
&& (lastError.getMessage() != null)) {
output.append("\n\t");
output.append(lastError.getMessage());
}
}
System.out.println(output);
if (arguments.printStackTrace()) {
lastError.printStackTrace();
}
continue;
}
}
output.append(" ");
output.append(MonitoredVmUtil.mainClass(vm,
arguments.showLongPaths()));
以下是activeVMs方法的代码:
/**
* Return the current set of monitorable Java Virtual Machines.
* <p>
* The set returned by this method depends on the user name passed
* to the constructor. If no user name was specified, then this
* method will return all candidate JVMs on the system. Otherwise,
* only the JVMs for the given user will be returned. This assumes
* that principal associated with this JVM has the appropriate
* permissions to access the target set of JVMs.
*
* @return Set - the Set of monitorable Java Virtual Machines
*/
public synchronized Set<Integer> activeVms() {
/*
* This method is synchronized because the Matcher object used by
* fileFilter is not safe for concurrent use, and this method is
* called by multiple threads. Before this method was synchronized,
* we'd see strange file names being matched by the matcher.
*/
Set<Integer> jvmSet = new HashSet<Integer>();
if (! tmpdir.isDirectory()) {
return jvmSet;
}
if (userName == null) {
/*
* get a list of all of the user temporary directories and
* iterate over the list to find any files within those directories.
*/
File[] dirs = tmpdir.listFiles(userFilter);
for (int i = 0 ; i < dirs.length; i ++) {
if (!dirs[i].isDirectory()) {
continue;
}
// get a list of files from the directory
File[] files = dirs[i].listFiles(fileFilter);
if (files != null) {
for (int j = 0; j < files.length; j++) {
if (files[j].isFile() && files[j].canRead()) {
jvmSet.add(new Integer(
PerfDataFile.getLocalVmId(files[j])));
}
}
}
}
} else {
/*
* Check if the user directory can be accessed. Any of these
* conditions may have asynchronously changed between subsequent
* calls to this method.
*/
// get the list of files from the specified user directory
File[] files = tmpdir.listFiles(fileFilter);
if (files != null) {
for (int j = 0; j < files.length; j++) {
if (files[j].isFile() && files[j].canRead()) {
jvmSet.add(new Integer(
PerfDataFile.getLocalVmId(files[j])));
}
}
}
}
// look for any 1.4.1 files
File[] files = tmpdir.listFiles(tmpFileFilter);
if (files != null) {
for (int j = 0; j < files.length; j++) {
if (files[j].isFile() && files[j].canRead()) {
jvmSet.add(new Integer(
PerfDataFile.getLocalVmId(files[j])));
}
}
}
return jvmSet;
}
}
通过这些,明白了jps的实现,原来并不是在不同的系统执行不同的命令,哈哈
分享到:
相关推荐
jps(Java Virtual Machine Process Status Tool)是JDK 1.5提供的一个显示当前所有java进程pid的命令,简单实用,非常适合在linux/unix平台上简单察看当前java进程的一些简单情况。 使用 先执行jps –help 查看一下此...
作用:获取java进程号,是后续命令的基础。 当一台服务器运行多个java进程时,该命令默认只输出进程号和应用名,可能无法区分哪个是自己需要分析的对象,这时候可以附加参数 -l,显示完整路径。此外,附加参数-v,可...
JPS算法的实现!(C#版本)
在一个集群非常大的情况下,如果想要查看单个主机在运行哪些java进程。我们可以去到每个主机下,使用jps命令。可是这种方法太过低效。我们可以使用一个shell脚本来完成此命令。查看进程 jps脚本 提前配置免密
jps java print service JAVA 打印
绍Java长期运行后, jps等工具无法连接jvm
用于查询所有节点的jps或者集体执行某个命令,如关机,如重启,如删除文件
带有网格图的 RTS 游戏的路径查找算法的 C++ 实现。 如何使用 此代码用于我的类似 RTS 的游戏中,带有自定义内部引擎。我照原样复制它,没有实现许多类,如 vec2、Array、MemoryManager 等。所以如果有人想使用它,...
基于JPS的网上书店设计与实现
在文件目录启动命令行窗口,输入python Main.py -v map.bmp即可运行
jps判断hadoop启动是否成功;分别对master和slave进行了判断。jps不是hadoop的什么命令,是java的命令,所以直接执行就行了。
编译安装JDK以后,如果原来的openjdk 没有卸载完毕,就会存在两个jvm虚拟机,需要定义以下默认的jvm。
交互图象JPS代码 网页图象交互。
我们一定会写一个shell脚本去每一个节点上去jps,查看每个节点的进程情况。 原先以为shell很简单: #!/bin/bash #查看每个节点运行情况 for((host=101;host<108;host++));do echo -----------hadoop$host--------...
jps1.1.2(java petstore)+J2EE_Petstore详解
jps:与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程号。 jstat:一个极强的监视VM内存工具。可以用来监视VM内存内的各种堆和非堆的大小及其内存使用量。 jmap:打印出...
kotlin-jps-plugin.jar
jps_stat:Bash脚本,监视当前linux系统上运行的所有Java程序的current_heap_memory,max_heap_till_now,current_ram,max_ram_used,current_cpu_by_jvm详细信息