引言
JPS 命令是日常开发过程中常常遇到的命令。应用起来也非常简单,本节内容次要翻译 Oracel 官网的 JPS 阐明,以及相干的实现原理剖析,最初介绍一些 JPS 无奈获取到 JAVA 过程的起因排查。
官网文档翻译
原文:jps – Java Virtual Machine Process Status Tool (oracle.com)
SYNOPSIS(简介)
jps [options] [hostid]
PARAMETERS
options
Command-line options.
hostid
The host identifier of the host for which the process report should be generated. The _hostid_ may include optional components that indicate the communications protocol, port number, and other implementation specific data.
host 惟一主机标识符号,这里理论指的是操作系统治理过程必须为应用程序调配的过程号,而后再由 JVM 对立治理资源标识。对立资源管理能够是协定,端口号和其余非凡数据。
OPTIONS
The jps command supports a number of options that modify the output of the command. These options are subject to change or removal in the future.
jps 命令反对许多批改命令输入的选项。这些选项未来可能会更改或删除。
-q:Suppress the output of the class name, JAR file name, and arguments passed to the main
method, producing only a list of local VM identifiers.
禁止 输入类名、JAR 文档名和传递给“main”办法的参数,仅生成本地 VM 标识符的列表。
[zxd@localhost ~]$ jps
10635 Jps
[zxd@localhost ~]$ jps -q
10647
-m:Output the arguments passed to the main method. The output may be null for embedded JVMs.
输入传递给 main 办法的参数。对于 嵌入式 JVM,输入可能为空。
[root@localhost bin]# jps -m
11057 seata-server.jar
10726 nacos-server.jar --spring.config.additional-location=file:/opt/nacos/conf/ --logging.config=/opt/nacos/conf/nacos-logback.xml --server.max-http-header-size=524288 nacos.nacos
11103 Jps -m
-l:Output the full package name for the application’s main class or the full path name to the application’s JAR file.
输入应用程序的启动 main 包的残缺名称或残缺门路。
[root@localhost bin]# jps -l
10726 /opt/nacos/target/nacos-server.jar
15831 sun.tools.jps.Jps
15742 /opt/seata/target/seata-server.jar
-v:Output the arguments passed to the JVM.
留神 小写,输入传递给 JVM 的参数。
[root@localhost bin]# jps -v
15843 Jps -Dapplication.home=/opt/jdk8 -Xms8m
10726 nacos-server.jar -Djava.ext.dirs=/opt/jdk8/jre/lib/ext:/opt/jdk8/lib/ext -Xms512m -Xmx512m -Xmn256m -Dnacos.standalone=true -Dnacos.member.list= -Xloggc:/opt/nacos/logs/nacos_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -Dloader.path=/opt/nacos/plugins,/opt/nacos/plugins/health,/opt/nacos/plugins/cmdb,/opt/nacos/plugins/selector -Dnacos.home=/opt/nacos
15742 seata-server.jar -Dloader.path=/opt/seata/lib -Xmx512m -Xms512m -Xmn256m -Xss512k -XX:SurvivorRatio=10 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:MaxDirectMemorySize=1024m -XX:-OmitStackTraceInFastThrow -XX:-UseAdaptiveSizePolicy -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/seata/logs/java_heapdump.hprof -XX:+DisableExplicitGC -Xloggc:/opt/seata/logs/seata_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -XX:+UseG1GC -Dio.netty.leakDetectionLevel=advanced -Dapp.name=seata-server -Dapp.pid=15703 -Dapp.home=/opt/seata -Dbasedir=/opt/seata -Dspring.config.location=/opt/seata/conf/application.yml -Dlogging.config=/opt/seata/conf/logback-spring.xml
-V:Output the arguments passed to the JVM through the flags file (the .hotspotrc file or the file specified by the -XX:Flags=<_filename_> argument).
留神大写,输入通过标记文档(.hotspotrc 文档或由 -XX:Flags=<_filename_> 参数指定的文档)传递给 JVM 的参数。
这个参数的成果从目前看来和默认的应用形式相似,并未看到本质的作用。
-J:_option_
Pass _option_ to the java launcher called by jps. For example, -J-Xms48m sets the startup memory to 48 megabytes. It is a common convention for -J to pass options to the underlying VM executing applications written in Java.
将 option 传递给 jps 调用的 java 启动器。例如,-J-Xms48m 将启动内存设置为 48 MB。-J 将选项传递给执行用 Java 编写的利用过程的底层 VM 是一种常见的约定。
HOST IDENTIFIER
接下来时第二个参数,如果不指定默认为本机的 JVM 程序,否则看以指定对应的主机
The host identifier, or _hostid_ is a string that indicates the target system. The syntax of the _hostid_ string largely corresponds to the syntax of a URI:
host 标识或者 hostid 以字符串模式显示在指标机器,\_hostid\_字符串的语法与 URI 的语法根本对应。
[protocol:][//]hostname] [:port][/servername]
protocol
The communications protocol. If the _protocol_ is omitted and a _hostname_ is not specified, the default protocol is a platform specific, optimized, local protocol. If the _protocol_ is omitted and a _hostname_ is specified, then the default protocol is rmi.
通信协议。如果省略 protocol 且未指定 hostname_,则默认协定是特定于平台的本地协定。如果省略 _protocol 并指定了 _hostname_,则默认协定为 rmi。
hostname
A hostname or IP address indicating the target host. If _hostname_ is omitted, then the target host is the local host.
批示指标主机的主机名或 IP 地址。如果省略 _hostname_,则指标主机是本地主机。
port
The default port for communicating with the remote server. If the _hostname_ is omitted or the _protocol_ specifies an optimized, local protocol, then _port_ is ignored. Otherwise, treatment of the _port_ parameter is implementation specific. For the default rmi protocol the _port_ indicates the port number for the rmiregistry on the remote host. If _port_ is omitted, and _protocol_ indicates rmi, then the default rmiregistry port (1099) is used.
用于与近程服务器通信的默认端口。如果省略 hostname 或 protocol 指定了优化的本地协定,则会疏忽 port_。否则,_port 参数的解决是特定于实现的。对于缺省的 rmi 协定,_port_ 批示近程主机上 rmiregistry 的端口号。如果省略 port_,并且 _protocol 示意 rmi,则应用默认的 rmiregistry 端口(1099)。
servername
The treatment of this parameter depends on the implementation. For the optimized, local protocol, this field is ignored. For the rmi protocol, this parameter is a string representing the name of the RMI remote object on the remote host. See the -n option for the jstatd command.
此参数的解决取决于实现。对于优化的本地协定,将疏忽此字段。对于 rmi 协定,此参数是一个字符串,示意近程主机上 RMI 近程对象的名称。请参阅 jstatd 命令的 -n 选项。
DESCRIPTION(形容)
The jps tool lists the instrumented HotSpot Java Virtual Machines (JVMs) on the target system. The tool is limited to reporting information on JVMs for which it has the access permissions.
JPS 的作用是列举指标 JVM 以后运行的所有程序,然而仅限于以后 JVM 接管的所有程序。
If jps is run without specifying a _hostid_, it will look for instrumented JVMs on the local host. If started with a _hostid_, it will look for JVMs on the indicated host, using the specified protocol and port.
JPS 运行的时候不是一个特地的 hostid,而是会在本地运行并且检测 JVM,并且看上去像是在 JVM 的过程李米娜,应用非凡的协定和端口。
A jstatd process is assumed to be running on the target host. The jps command will report the local VM identifier, or _lvmid_, for each instrumented JVM found on the target system. The lvmid is typically, but not necessarily, the operating system’s process identifier for the JVM process. With no options, jps will list each Java application’s _lvmid_ followed by the short form of the application’s class name or jar file name. The short form of the class name or JAR file name omits the class’s package information or the JAR files path information.
假如指标主机上有一个 jstatd 过程正在运行,JPS 命令会报告以后的 VM 标识或者 lvmid,对于在指标零碎上发现的每个工具化的 JVM 来说,lvmid 是广泛然而必要的,由操作系统的过程标识
The jps command uses the java launcher to find the class name and arguments passed to the main
method. If the target JVM is started with a custom launcher, the class name (or JAR file name) and the arguments to the main
method will not be available. In this case, the jps command will output the string _Unknown_ for the class name or JAR file name and for the arguments to the main method.
jps 命令应用 java 启动器来查找传递给 ‘main’ 办法的类名和参数。如果指标 JVM 是应用定制启动器启动的,那幺类名(或 JAR 文档名)和 ‘main’ 办法的参数将不可用。在这种状况下,jps 命令将输入字符串 Unknown 作为类名或 JAR 文档名以及 main 办法的参数。
The list of JVMs produced by the jps command may be limited by the permissions granted to the principal running the command. The command will only list the JVMs for which the principle has access rights as determined by operating system specific access control mechanisms.
由 jps 命令生成的 JVM 列表可能受到授予运行该命令的主体的权限的限度。命令将仅列出主体具备拜访权限的 JVM,该拜访权限由特定于操作系统的访问控制机制确定。
NOTE: This utility is unsupported and may not be available in future versions of the JDK. It is not currently available on Windows 98 and Windows ME platforms.
此实用过程在将来 JDK 版本中可能会不受反对,并且在局部老旧操作系统是不反对的。
OUTPUT FORMAT
The output of the jps command follows the following pattern:
lvmid [[ classname | JARfilename | “Unknown”] [_arg_ ] [jvmarg ] ]
Where all output tokens are separated by white space. An _arg_ that includes embedded white space will introduce ambiguity when attempting to map arguments to their actual positional parameters.
其中所有输入标记都用空格分隔。蕴含嵌入空格的 arg 在尝试将参数映射到其理论地位参数时会引入歧义。
NOTE: You are advised not to write scripts to parse jps output since the format may change in future releases. If you choose to write scripts that parse jps output, expect to modify them for future releases of this tool.
留神:建议您不要编写脚本来解析 jps 输入,因为格局可能会在未来的版本中发生变化。如果抉择编写剖析 jps 输入的脚本,请为此工具的将来版本批改它们。
EXAMPLES
This section provides examples of the jps command.
上面是 JPS 命令应用的一些案例:
Listing the instrumented JVMs on the local host:
列出以后机器容许的 JVM:
jps
18027 Java2Demo.JAR
18032 jps
18005 jstat
Listing the instrumented JVMs on a remote host:
This example assumes that the jstat server and either the its internal RMI registry or a separate external rmiregistry process are running on the remote host on the default port (port 1099). It also assumes that the local host has appropriate permissions to access the remote host. This example also includes the _-l_ option to output the long form of the class names or JAR file names.
此示例假设 jstat 服务器及其外部 RMI 注册表或独自的内部 rmiregistry 过程在近程机上的缺省端口(端口 1099)上运行。它还假设本地主机具备拜访近程主机的适当权限。此示例还包含 -l 选项,用于输入类名或 JAR 文档名的长格局。
jps -l remote.domain
3002 /opt/jdk1.7.0/demo/jfc/Java2D/Java2Demo.JAR
2857 sun.tools.jstatd.jstatd
Listing the instrumented JVMs on a remote host with a non-default port for the RMI registry
This example assumes that the jstatd server, with an internal RMI registry bound to port 2002, is running on the remote host. This example also uses the _-m_ option to include the arguments passed to the _main_ method of each of the listed Java applications.
上面是一个打印近程服务器的 JVM 运行状况。
此示例假设近程主机上正在运行具备绑定到端口 2002 的外部 RMI 注册表的 jstatd 服务器。此示例还应用 -m 选项来蕴含传递给列出的每个 Java 利用过程的 main 办法的参数
jps -m remote.domain:2002
3002 /opt/jdk1.7.0/demo/jfc/Java2D/Java2Demo.JAR
3102 sun.tools.jstatd.jstatd -p 2002
SEE ALSO
- java – the Java Application Launcher
- jstat – the Java virtual machine Statistics Monitoring Tool
- jstatd – the jstat daemon
- rmiregistry – the Java Remote Object Registry
实现原理
jps 的命令是在 $JAVA_HOME/bin
上面存在的,显然和每个 JVM 启动都有密切关系的,既然 JPS 要收集所有 JVM 的信息:
[root@localhost bin]# ls /opt/jdk8/bin/
appletviewer jarsigner javah jcmd jhat jrunscript jvisualvm policytool serialver wsimport
ControlPanel java javap jconsole jinfo jsadebugd keytool rmic servertool xjc
extcheck javac javapackager jcontrol jjs jstack native2ascii rmid tnameserv
idlj javadoc java-rmi.cgi jdb jmap jstat orbd rmiregistry unpack200
jar javafxpackager javaws jdeps jps jstatd pack200 schemagen wsgen
java 程序在启动当前,会在 java.io.tmpdir
指定的目录下,就是长期文件夹里,在 Linux 中会生成一个相似于hsperfdata_User(User 为登录用户)的文件夹,这个文件夹里(在 Linux 中为/tmp/hsperfdata_{userName}/
)有几个文件,名字就是java 过程的 pid,因而列出以后运行的 java 过程,只是把这个目录里的文件名列一下而已。至于零碎的参数什么,就能够解析这几个文件取得。
咱们能够理论运行试验看一下:
[root@localhost tmp]# cd /tmp/hsperfdata_root/
[root@localhost hsperfdata_root]# ls
10726 15742
[root@localhost hsperfdata_root]# jps
10726 nacos-server.jar
15742 seata-server.jar
16270 Jps
咱们通过过程号能够看到是能够对应上的。java.nio.file.TempFileHelper
中保留着临时文件的构建逻辑,留神这里对文件夹做了一层平安加密,避免内部利用篡改。
// temporary directory location
private static final Path tmpdir =
Paths.get(doPrivileged(new GetPropertyAction("java.io.tmpdir")));
JPS 生效解决
因为 JPS 须要有对应的 JVM 须要具备拜访权限才能够查看,对于内嵌的 JVM 是无奈利用 JPS 查看。所以有时候会呈现用 ps -ef|grep java
能看到启动的 java 过程,然而用 jps 查看却不存在该过程的 id。
对于这样的 JPS 生效场景,咱们能够通过上面的一些要点排查:
- 磁盘读写、目录权限问题 若该用户没有权限写 /tmp 目录或是磁盘已满,则无奈创立 /tmp/hsperfdata_userName/pid 文件。
-
临时文件失落,被删除或是定期清理。比拟常见的文件失落起因可能是 定时删除长期目录的工具 ,比方
crontab
、redhat
的tmpwatch
、ubuntu
的tmpreaper
等等用 jconsole 监控过程,发现在某一时段后过程依然存在,然而却没有监控信息了。
- JAVA 的过程信息存储被转移,JPS 是无奈收集到这一类信息的,比方内嵌的 JVM,此外 java 启动时提供了参数 (-Djava.io.tmpdir) 能够轻松批改过程信息启动和存储目录。然而这个设置的扭转会导致 JPS 和 Jconsole 无奈读取到。
杀过程
这里介绍比拟常见然而实际上 齐全不举荐应用 的办法:
[root@localhost hsperfdata_root]# jps
10726 nacos-server.jar
16779 Jps
15742 seata-server.jar
[root@localhost hsperfdata_root]# kill -9 15742
当然 ps -ef | grep java
或者应用 ps -aux | grep java
查找过程号,而后 kill -9 过程号
,这个过程号在搜寻后果外面处于 第二列 ,比方这里如果我想要 kill 掉 dashboard,就能够应用kill -9 4002
完结过程:
ps -ef | grep java 的内容:
root 4002 3942 0 14:56 pts/0 00:00:00 sh -c java $JAVA_OPTS -jar /rocketmq-dashboard.jar
root 4628 4002 0 14:56 pts/0 00:01:58 java -Drocketmq.namesrv.addr=192.168.58.128:9876 -jar /rocketmq-dashboard.jar
3000 4997 4916 0 14:56 ? 00:01:08 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.332.b09-1.el7_9.x86_64/bin/java -server -Xms909M -Xmx909M -Xmn200M -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:-UseParNewGC -verbose:gc -Xloggc:/dev/shm/rmq_srv_gc.log -XX:+PrintGCDetails -XX:-OmitStackTraceInFastThrow -XX:-UseLargePages -Djava.ext.dirs=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.332.b09-1.el7_9.x86_64/jre/lib/ext:/home/rocketmq/rocketmq-4.9.4/bin/../lib -cp .:/home/rocketmq/rocketmq-4.9.4/bin/../conf: org.apache.rocketmq.namesrv.NamesrvStartup
root 10726 1 0 15:44 pts/0 00:04:14 /opt/jdk8/bin/java -Djava.ext.dirs=/opt/jdk8/jre/lib/ext:/opt/jdk8/lib/ext -Xms512m -Xmx512m -Xmn256m -Dnacos.standalone=true -Dnacos.member.list= -Xloggc:/opt/nacos/logs/nacos_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -Dloader.path=/opt/nacos/plugins,/opt/nacos/plugins/health,/opt/nacos/plugins/cmdb,/opt/nacos/plugins/selector -Dnacos.home=/opt/nacos -jar /opt/nacos/target/nacos-server.jar --spring.config.additional-location=file:/opt/nacos/conf/ --logging.config=/opt/nacos/conf/nacos-logback.xml --server.max-http-header-size=524288 nacos.nacos
3000 15416 15395 3 16:05 ? 00:16:22 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.332.b09-1.el7_9.x86_64/bin/java -server -Xms909M -Xmx909M -Xmn200M -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8 -verbose:gc -Xloggc:/dev/shm/mq_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m -XX:-OmitStackTraceInFastThrow -XX:+AlwaysPreTouch -XX:MaxDirectMemorySize=909M -XX:-UseLargePages -XX:-UseBiasedLocking -Djava.ext.dirs=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.332.b09-1.el7_9.x86_64/jre/lib/ext:/home/rocketmq/rocketmq-4.9.4/bin/../lib -cp .:/home/rocketmq/rocketmq-4.9.4/bin/../conf: org.apache.rocketmq.broker.BrokerStartup -c ../conf/broker.conf
root 16809 10683 0 22:56 pts/0 00:00:00 grep --color=auto java
ps -aux | grep java 的内容:
root 4002 0.0 0.0 4324 8 pts/0 Ss+ 14:56 0:00 sh -c java $JAVA_OPTS -jar /rocketmq-dashboard.jar
root 4628 0.4 6.8 2983732 128476 pts/0 Sl+ 14:56 1:58 java -Drocketmq.namesrv.addr=192.168.58.128:9876 -jar /rocketmq-dashboard.jar
3000 4997 0.2 7.5 3445320 141516 ? Sl 14:56 1:08 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.332.b09-1.el7_9.x86_64/bin/java -server -Xms909M -Xmx909M -Xmn200M -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:-UseParNewGC -verbose:gc -Xloggc:/dev/shm/rmq_srv_gc.log -XX:+PrintGCDetails -XX:-OmitStackTraceInFastThrow -XX:-UseLargePages -Djava.ext.dirs=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.332.b09-1.el7_9.x86_64/jre/lib/ext:/home/rocketmq/rocketmq-4.9.4/bin/../lib -cp .:/home/rocketmq/rocketmq-4.9.4/bin/../conf: org.apache.rocketmq.namesrv.NamesrvStartup
root 10726 0.9 27.1 3533976 506316 pts/0 Sl 15:44 4:15 /opt/jdk8/bin/java -Djava.ext.dirs=/opt/jdk8/jre/lib/ext:/opt/jdk8/lib/ext -Xms512m -Xmx512m -Xmn256m -Dnacos.standalone=true -Dnacos.member.list= -Xloggc:/opt/nacos/logs/nacos_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -Dloader.path=/opt/nacos/plugins,/opt/nacos/plugins/health,/opt/nacos/plugins/cmdb,/opt/nacos/plugins/selector -Dnacos.home=/opt/nacos -jar /opt/nacos/target/nacos-server.jar --spring.config.additional-location=file:/opt/nacos/conf/ --logging.config=/opt/nacos/conf/nacos-logback.xml --server.max-http-header-size=524288 nacos.nacos
3000 15416 3.9 17.3 5065612 322680 ? Sl 16:05 16:31 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.332.b09-1.el7_9.x86_64/bin/java -server -Xms909M -Xmx909M -Xmn200M -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8 -verbose:gc -Xloggc:/dev/shm/mq_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m -XX:-OmitStackTraceInFastThrow -XX:+AlwaysPreTouch -XX:MaxDirectMemorySize=909M -XX:-UseLargePages -XX:-UseBiasedLocking -Djava.ext.dirs=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.332.b09-1.el7_9.x86_64/jre/lib/ext:/home/rocketmq/rocketmq-4.9.4/bin/../lib -cp .:/home/rocketmq/rocketmq-4.9.4/bin/../conf: org.apache.rocketmq.broker.BrokerStartup -c ../conf/broker.conf
root 16817 0.0 0.0 112816 980 pts/0 S+ 23:00 0:00 grep --color=auto java
写在最初
JPS 总体上是一些其余 JVM 工具的疏导,比方 Jstat 须要依赖 JPS 获取的过程号进行性能优化和问题排查,JConsole
工具来监控 JVM 的运行状况。