`
chainhou
  • 浏览: 174614 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

获取当前用户所有java进程及jps命令的实现

阅读更多
我们在开发中经常会遇到这样的问题,需要把本地运行的所有某个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进程的jstack信息示例分享 通过线程堆栈信息分析java线程

    以上脚本首先定义了Java进程的名称,然后通过ps命令配合grep找到所有java进程,并且排除掉grep自身产生的进程。之后,它使用date命令生成一个时间戳,以便于日志文件的命名。对于每个找到的进程ID,脚本会将jstack...

    linux下查看java进程下线程占用cpu情况

    通过以上方法,你可以深入了解Linux下Java进程及线程对CPU的占用情况,从而进行问题定位和性能优化。在实际操作中,通常会结合多个工具和方法,以便从不同角度全面分析。记得,持续监控和分析是找出问题的关键。

    一篇文章让你了解chaosblade-niaoshuai1

    在进行实验前,你需要找到目标 JVM 进程的 ID,可以通过 `jps -v` 命令查看。然后,使用 `blade prepare jvm --process &lt;PID&gt;` 来为指定的 JVM 进程挂载一个沙箱,这样 ChaosBlade 就可以在不实际影响生产环境的情况...

    亲测可用java-1.8.0-openjdk.linux.x86_64.zip

    3. **JPS命令**:`jps`是Java进程状况工具(Java Process Status)的缩写,它是JDK提供的一种实用程序,用于显示当前系统中正在运行的Java虚拟机实例。使用`jps`命令,开发者可以轻松地查看哪些Java应用程序正在运行...

    Java2语言命令详解

    `jps`列出正在运行的Java进程ID,方便定位和管理Java应用程序。无需参数即可运行: ``` jps ``` 7. **jstat** - 统计信息工具 `jstat`用于收集JVM的各种统计信息,如垃圾收集、内存使用等。例如,查看`1234`...

    Linux 环境如何使用 kill 命令优雅停止 Java 服务.pdf

    jps命令是Java提供的一个小工具,专门用来列出JVM的运行实例及相关信息。而ps命令则是Linux中的进程查看命令,可以列出系统中运行的所有进程。找到进程ID后,就可以使用kill命令来发送停止信号。 关于kill命令,...

    jps_stat:Bash脚本,监视当前linux系统上运行的所有Java程序的current_heap_memory,max_heap_till_now,current_ram,max_ram_used,current_cpu_by_jvm详细信息

    它结合了`jps`(Java进程状态)和`jstat`(Java统计监测工具)命令的功能,提供了更详细的性能指标,包括`current_heap_memory`(当前堆内存使用量)、`max_heap_till_now`(至今为止的最大堆内存使用量)、`current...

    Java内存泄露_JVM监控工具介绍

    jdb命令是一个强大的调试工具,用于对core文件和正在运行的Java进程进行实时地调试。jdb工具可以帮助开发者快速地定位问题所在,并提供丰富的命令帮助开发者进行调试。 六、jstat命令 jstat命令是一个实时的命令行...

    springboot做的天气查看及jps定位

    在本项目中,"springboot做的天气查看及jps定位"是一个使用Spring Boot框架构建的应用,它整合了天气查询功能并结合了Java进程状态检查工具(JPS)。这个应用展示了Spring Boot如何优雅地将多种服务集成在一起,为...

    JAVA命令大全.pdf

    9. jps.exe:JVM进程状态工具,用于列出当前系统中所有Java虚拟机的进程信息,包括进程ID、主类等。 10. jstat.exe:JVM统计监控工具,用于监视Java虚拟机中各种运行时组件的行为,例如堆内存使用情况、垃圾回收...

    java诊断与调优常用命令jmap、jstack、jstat使用实战.pdf

    2. **jmap**: 这个命令用于获取Java进程的内存使用情况。例如,`jmap -heap [进程ID]` 可以显示堆内存的详细信息,包括eden区、survivor区和old区的使用情况。`jmap -histo [进程ID]` 可以按类型统计对象数量和占用...

    使用python来简单实现jdk几个指令.zip

    它可能包含了如何连接到Java进程,如何获取并解析`jps`和`jstat`类似信息的示例代码。分析这个文件可以帮助我们理解具体的实现细节。 在实际项目中,使用Python模拟Java指令可以为那些需要跨平台或集成现有Python...

    windows运行jar包和开机自动启动.docx

    jps 命令可以查看当前的 Java 进程,例如: jps 4. 使用 TASKKILL 命令终止进程 TASKKILL 命令可以终止进程,例如: TASKKILL /F /PID 10116 5. 自动获取 PID 并终止 JAR 进程 使用 for 循环可以自动获取 ...

    Linux常用的六十条命令

    58. jps命令:显示当前系统中的 Java 进程。 59. nohup命令:在后台执行命令。 60. uname命令:显示系统的信息。 系统信息 61. hostname命令:显示当前主机的名称。 62. top命令:显示当前系统中的进程列表。 63. ...

    Java获取系统信息(cpu,内存,硬盘,进程等)的相关方法.pdf

    关于进程信息的获取,Java同样提供了一些API可以用来列举和管理Java进程内部的线程。`Thread`类中的`getThreadGroup()`方法可以用来获取当前线程的线程组,通过递归地获取到线程组的父线程组,可以列举出全部活跃的...

    java程序运行跟踪利器Btrace分享

    2. **查找Java进程**:使用`jps`命令可以查看当前系统中正在运行的Java进程,找出你想要监控的进程ID(pid)。 3. **运行脚本**:进入你的Btrace脚本所在目录,然后使用`btrace pid 脚本文件名`命令,将pid替换为你...

    show-busy-java-threads.sh文件

    `show-busy-java-threads.sh`脚本通过JVM提供的命令行工具`jstack`来获取当前Java进程的线程堆栈信息,从而揭示这些繁忙线程的详细状态。 `jstack`是Java标准工具包(JDK)的一部分,它能输出Java虚拟机(JVM)中...

    java问题快速定位

    - `jstack [pid] &gt; output.txt`:将当前Java进程的线程堆栈信息导出到指定文件中。 - `jstack -l [pid]`:列出所有线程的详细信息。 当遇到应用响应慢或者无响应的情况时,通过`jstack`可以获取到线程的详细状态...

    JVM调优工具命令详解.pdf

    首先,文档提到了JPS命令,它用于查看当前运行的Java进程信息,并返回进程ID,这是进行JVM调优的起始步骤。利用JPS获取进程ID后,便可以通过JVM自带的jmap命令来进一步分析进程内存使用情况。jmap命令能够帮助开发者...

    java—JDK内置工具使用技巧详解

    - **功能**:jps 用于列出当前所有 Java 进程的信息,包括进程 ID 和主类名等。 - **使用场景**:当需要查找某个特定 Java 应用的进程 ID 时非常有用。 - **命令格式**:`jps [options]` #### 三、具体案例分析 ...

Global site tag (gtag.js) - Google Analytics