我们在开发中经常会遇到这样的问题,需要把本地运行的所有某个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的实现,原来并不是在不同的系统执行不同的命令,哈哈
分享到:
相关推荐
以上脚本首先定义了Java进程的名称,然后通过ps命令配合grep找到所有java进程,并且排除掉grep自身产生的进程。之后,它使用date命令生成一个时间戳,以便于日志文件的命名。对于每个找到的进程ID,脚本会将jstack...
通过以上方法,你可以深入了解Linux下Java进程及线程对CPU的占用情况,从而进行问题定位和性能优化。在实际操作中,通常会结合多个工具和方法,以便从不同角度全面分析。记得,持续监控和分析是找出问题的关键。
在进行实验前,你需要找到目标 JVM 进程的 ID,可以通过 `jps -v` 命令查看。然后,使用 `blade prepare jvm --process <PID>` 来为指定的 JVM 进程挂载一个沙箱,这样 ChaosBlade 就可以在不实际影响生产环境的情况...
3. **JPS命令**:`jps`是Java进程状况工具(Java Process Status)的缩写,它是JDK提供的一种实用程序,用于显示当前系统中正在运行的Java虚拟机实例。使用`jps`命令,开发者可以轻松地查看哪些Java应用程序正在运行...
`jps`列出正在运行的Java进程ID,方便定位和管理Java应用程序。无需参数即可运行: ``` jps ``` 7. **jstat** - 统计信息工具 `jstat`用于收集JVM的各种统计信息,如垃圾收集、内存使用等。例如,查看`1234`...
jps命令是Java提供的一个小工具,专门用来列出JVM的运行实例及相关信息。而ps命令则是Linux中的进程查看命令,可以列出系统中运行的所有进程。找到进程ID后,就可以使用kill命令来发送停止信号。 关于kill命令,...
它结合了`jps`(Java进程状态)和`jstat`(Java统计监测工具)命令的功能,提供了更详细的性能指标,包括`current_heap_memory`(当前堆内存使用量)、`max_heap_till_now`(至今为止的最大堆内存使用量)、`current...
jdb命令是一个强大的调试工具,用于对core文件和正在运行的Java进程进行实时地调试。jdb工具可以帮助开发者快速地定位问题所在,并提供丰富的命令帮助开发者进行调试。 六、jstat命令 jstat命令是一个实时的命令行...
在本项目中,"springboot做的天气查看及jps定位"是一个使用Spring Boot框架构建的应用,它整合了天气查询功能并结合了Java进程状态检查工具(JPS)。这个应用展示了Spring Boot如何优雅地将多种服务集成在一起,为...
9. jps.exe:JVM进程状态工具,用于列出当前系统中所有Java虚拟机的进程信息,包括进程ID、主类等。 10. jstat.exe:JVM统计监控工具,用于监视Java虚拟机中各种运行时组件的行为,例如堆内存使用情况、垃圾回收...
2. **jmap**: 这个命令用于获取Java进程的内存使用情况。例如,`jmap -heap [进程ID]` 可以显示堆内存的详细信息,包括eden区、survivor区和old区的使用情况。`jmap -histo [进程ID]` 可以按类型统计对象数量和占用...
它可能包含了如何连接到Java进程,如何获取并解析`jps`和`jstat`类似信息的示例代码。分析这个文件可以帮助我们理解具体的实现细节。 在实际项目中,使用Python模拟Java指令可以为那些需要跨平台或集成现有Python...
jps 命令可以查看当前的 Java 进程,例如: jps 4. 使用 TASKKILL 命令终止进程 TASKKILL 命令可以终止进程,例如: TASKKILL /F /PID 10116 5. 自动获取 PID 并终止 JAR 进程 使用 for 循环可以自动获取 ...
58. jps命令:显示当前系统中的 Java 进程。 59. nohup命令:在后台执行命令。 60. uname命令:显示系统的信息。 系统信息 61. hostname命令:显示当前主机的名称。 62. top命令:显示当前系统中的进程列表。 63. ...
关于进程信息的获取,Java同样提供了一些API可以用来列举和管理Java进程内部的线程。`Thread`类中的`getThreadGroup()`方法可以用来获取当前线程的线程组,通过递归地获取到线程组的父线程组,可以列举出全部活跃的...
2. **查找Java进程**:使用`jps`命令可以查看当前系统中正在运行的Java进程,找出你想要监控的进程ID(pid)。 3. **运行脚本**:进入你的Btrace脚本所在目录,然后使用`btrace pid 脚本文件名`命令,将pid替换为你...
`show-busy-java-threads.sh`脚本通过JVM提供的命令行工具`jstack`来获取当前Java进程的线程堆栈信息,从而揭示这些繁忙线程的详细状态。 `jstack`是Java标准工具包(JDK)的一部分,它能输出Java虚拟机(JVM)中...
- `jstack [pid] > output.txt`:将当前Java进程的线程堆栈信息导出到指定文件中。 - `jstack -l [pid]`:列出所有线程的详细信息。 当遇到应用响应慢或者无响应的情况时,通过`jstack`可以获取到线程的详细状态...
首先,文档提到了JPS命令,它用于查看当前运行的Java进程信息,并返回进程ID,这是进行JVM调优的起始步骤。利用JPS获取进程ID后,便可以通过JVM自带的jmap命令来进一步分析进程内存使用情况。jmap命令能够帮助开发者...
- **功能**:jps 用于列出当前所有 Java 进程的信息,包括进程 ID 和主类名等。 - **使用场景**:当需要查找某个特定 Java 应用的进程 ID 时非常有用。 - **命令格式**:`jps [options]` #### 三、具体案例分析 ...