jvm常用命令工具之jps
2023-05-23 16:44:33 阿炯

Jps(JVM Process Status Tool)是jdk 1.5提供的一个查看当前java进程的小工具, 可以看做是JavaVirtual Machine Process Status Tool的缩写。类似于 linux 的 ps 命令,但是它只列出系统中所有的 Java 应用程序。通过它可以方便地查看 Java 进程的启动类、传入参数和 Java 虚拟机参数等信息。列出正在运行的虚拟机进程,显示虚拟机正在执行的main()函数,及这些进程的ID(LVMID,Local Virsul Machine  ID),当显示的是本地虚拟机正常的时候,则该值与ps命令中显示的操作系统进程编号相等。

它可用于显示当前运行的java进程以及相关参数,实现机制如下:java程序在启动以后,会将jvm perfdata写入到java.io.tmpdir指定的目录下以进程号命名的文件中,就是在系统级的临时目录里生成一个类似于hsperfdata_User的文件夹,这个文件夹里(在Linux中为/tmp/hsperfdata_{userName}/),有几个文件,名字就是java进程的pid,因此列出当前运行的java进程,只是把这个目录里的文件名列一下而已。至于系统的参数什么,就可以解析这几个文件获得。

原理:java程序在启动以后,会在java.io.tmpdir指定的目录下,就是临时文件夹里生成一个类似于hsperfdata_User的文件夹,此目录中(在Linux中为/tmp/hsperfdata_{userName}/)有几个二进制文件,名字就是java进程的pid,因此列出当前运行的java进程,只是把这个目录里的文件名列一下而已。至于系统的参数什么,就可以解析这几个文件获得。

首先从特定的主机上获取正在运行的Java进程,然后对这些进程进行输出,如果有参数的话还要额外输出参数需要输出的信息。从主机获取Java进程主要有分为两种,一种是本地的,另一种通过RMI远程调用的。

在Windows系统下,默认路径为 C:\Users\username\AppData\Local\Temp\hsperfdata_username,而在Linux系统下,默认路径为/tmp/hsperfdata_username。

注:Windows中的临时文件可能为隐藏文件。

用法

命令格式:jps [options ] [ hostid ]
[options]选项:
-q:只输出进程 ID,只显示Java进程的lvmid,不显示class名称、jar文件名和传递给main 方法的参数等
-m:输出传入 main 方法的参数
-l:输出完全的包名,应用主类名,jar的完全路径名
-v:输出传递给jvm参数
-V:输出通过flag文件传递到JVM中的参数,即通过标识文件来输出传递给JVM的参数(即.hotspotrc文件或者由参数-XX:Flags=确定的文件)

hostid:需要查看Java进程的系统,由主机名和端口号来确定

<hostid>指定目标服务器,它的语法如是:[protocol:][[//]hostname][:port][/servername];
protocol - 如果protocol及hostname都没有指定,那表示的是与当前环境相关的本地协议,如果指定了hostname却没有指定protocol,那么protocol的默认就是rmi;
hostname - 服务器的IP或者名称,没有指定则表示本机;
port - 远程rmi的端口,如果没有指定则默认为1099;
ServerName - 注册到RMI注册中心中的jstatd的名称。

注:查看本地Java进程不需要hostid参数,如果要查看远程进程,需要在远程主机提供jstatd服务和RMI绑定。

输出结果格式为 lvmid [ [ classname | JARfilename | "Unknown"] [ arg* ] [ jvmarg* ] ]


失效处理

现象:用ps -ef|grep java能看到启动的java进程,但是用jps查看却不存在该进程的id。待会儿解释过之后就能知道在该情况下,jconsole、jvisualvm可能无法监控该进程,其他java自带工具也可能无法使用。

分析:
jps、jconsole、jvisualvm等工具的数据来源就是这个文件(/tmp/hsperfdata_userName/pid)。所以当该文件不存在或是无法读取时就会出现jps无法查看该进程号,jconsole无法监控等问题。

原因:
1).磁盘读写、目录权限问题 若该用户没有权限写/tmp目录或是磁盘已满,则无法创建/tmp/hsperfdata_userName/pid文件。或该文件已经生成,但用户没有读权限

2).临时文件丢失,被删除或是定期清理,对于linux机器,一般都会存在定时任务对临时文件夹进行清理,导致/tmp目录被清空。常用的可能定时删除临时目录的工具为crontab、redhat的tmpwatch、ubuntu的tmpreaper等等。这个导致的现象可能会是这样,用jconsole监控进程,发现在某一时段后进程仍然存在,但是却没有监控信息了。

3).java进程信息文件存储地址被设置不在/tmp目录下,上面在介绍时说默认会在/tmp/hsperfdata_userName目录保存进程信息,但由于以上1、2所述原因,可能导致该文件无法生成或是丢失,所以java启动时提供了参数(-Djava.io.tmpdir),可以对这个文件的位置进行设置,而jps、jconsole都只会从/tmp目录读取,而无法从设置后的目录读物信息


-XX:+UsePerfData
Enables the perfdata feature. This option is enabled by default to allow JVM monitoring and performance testing. Disabling it suppresses the creation of the hsperfdata_userid directories. To disable the perfdata feature, specify -XX:-UsePerfData.

jps 不带option的时候,默认列出JVM标示符号(PID)和简单的主类名或jar名称。

jps -q 只输出JVM进程的PID,不显示 class 名称,jar 文件名和传递给 main 方法的参数

jps -m 输出传递给 main 方法的参数,在嵌入式 jvm 上可能是 null

jps -l 输出应用程序主类的完整包名或者应用程序的 jar 文件完整路径名

jps -v 输出传递给 JVM 的参数


Hadoop下相关用户的进程信息

pid文件默认存放路径:/tmp/hsperfdata_(用户名称)/{pid,pid,pid...};该文件的重要性:缺少pid文件,启动停止都会有问题,在其停止脚本stop-dfs.sh中就会发现其需要寻找pid。在 hadoop-env.sh 文件修改pid的路径:
export HADOOP_PID_DIR=${HADOOP_PID_DIR}
将其修改到自己要设置的路径目录下就可以了。

pid文件删除,不影响服务正常运行和用户的读写,但:
stop –>关闭不掉
start –>另起一个进程

如果删除pid文件,则会导致停止服务的时候有问题。同时linux对/tmp目录有30天删除不常用文件或文件夹的情况,所以需要修改pid文件存储路径:
export HADOOP_PID_DIR=/freeoa.net/tmp

关闭hdfs时抛出:no namenode to stop,但是namenode这个进程还存在,关掉pid文件会关闭不了进程;在重启之后查看namenode的pid文件时,发现不是之前的,删掉 pid后重启造成系统进程混乱。

重启之前kill掉之前的进程时,务必要清除残留的pid文件和jps目录文件,pid文件的删除或者残留虽然对当前的服务进程没有影响,但是当涉及关闭或重启肯定会有影响,关闭之后最好是需要到/tmp目录下检查一下有没有pid文件残留以及jps命令有没有清空,确保重启之前这些文件是干净的。所以有时需要将pid文件的存储路径修改,而不是默认放在/tmp目录下,况且/tmp目录是每月清空一次的,如果是一些很重要的文件或者进程放到了/tmp目录下,也是会有风险的,所以一些重要的文件像pid文件这种默认路径的就要重新设置路径。

jps命令查看出现'process information unavailable'问题
root用个可查看所有用户的进程
普通用户只能查看自己的进程

root用户也可能有此提示。如果进程被kill了,有可能jps还是显示xxxx – process information unavailable,需要用ps -ef | grep pid 确认。当使用root用户kill掉hadoop进程后,/tmp/hsperfdata_hadoop目录下的进程pid文件仍然存在,将pid文件删除即可;当然也可能是被操作系统的OOM killer所处理的。


参考来源:

盘点一些java性能监控及工具