一、jps命令
1. 介绍
jps(Java Virtual Machine Process Status Tool)工具用于显示当前系统的进程情况,可以使用该命令查看当前服务器的Java进程,该工具比较简单,我们来看下:
deploy@127.0.0.1:~$ jps -help
usage: jps [-help]
jps [-q] [-mlvV] [<hostid>]
Definitions:
<hostid>: <hostname>[:<port>]
我们来简单看下它的命令格式:jps [参数] [hostid]
,其中参数为:
-q 仅显示Java进程id,不包含类名等其他信息
-m 输出传递给main方法的参数
-l 输出应用程序main class的完整包名或者 应用程序的jar文件完整路径名
-v 输出进程所对应的jvm参数
-V 输出通过flag文件传递到JVM中的参数(.hotspotrc文件或-XX:Flags=所指定的文件
-Joption 传递参数到vm,例如:-J-Xms48m
而hostid格式为:
[protocol:][[//]hostname][:port][/servername]
2. 使用
接下来,我们来简单看下它的使用。
1)首先,我们来看下该命令默认情况下的展示及加上相关参数的展示:
deploy@127.0.0.1:~$ jps
27075 BootStrap
3875 App
29049 Jps
可以看到,只展示进程名称及进程id,这里可以看到jps命令也开了一个进程,因为jps其实也是一个Java命令,也要占一个进程的;然后使用jps -l
:
deploy@127.0.0.1:~$ jps -l
27075 com.test.spring.boot.BootStrap
3875 com.test.log.App
29415 sun.tools.jps.Jps
展示进程id及进程对应的完整的包名称;
2)接下来使用jps -v
:
deploy@127.0.0.1:~$ jps -v
27075 BootStrap -Xms5120m -Xmx5120m -Xmn2560m -XX:MaxMetaspaceSize=128m -XX:MetaspaceSize=128m -Dfile.encoding=UTF-8 -XX:+UseConcMarkSweepGC ...(省略)
3875 App -Dfile.encoding=UTF-8 -Xms128m -Xmx512m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseCMSCompactAtFullCollection ...(省略)
29455 Jps -Denv.class.path=.:/usr/java/jdk1.8.0_66/lib/tools.jar:/usr/java/jdk1.8.0_66/lib/dt.jar -Dapplication.home=/usr/java/jdk1.8.0_66 -Xms8m
由于JVM展示的内容比较多,所以这里就省略了。我们可以从这里看到JVM的一些配置参数,并且可以看到JVM日志的输出路径,可以很方便的帮助我们定位问题。
3)接下来我们看下 jps -q
和 jps -m
:
deploy@127.0.0.1:~$ jps -q
29474
27075
3875
deploy@127.0.0.1:~$ jps -m
29601 Jps -m
27075 BootStrap /workspace/test/SprintTest/conf/test.json
3875 App /workspace/test/LogTest/conf/test.json
可以看到,-q命令只展示进程号,而-m则是主方法的参数。
4)一般情况下,我们使用比较多的是jps -mlv
参数;
5)获取元操服务器jps信息
jps命令是支持查看远程服务上的JVM进程信息的,但如果要查看其他机器上的JVM进程,需要在待查看机器上开启 jstatd 服务;
3. 原理
java程序在启动后,会在java.io.tmpdir指定的目录下,就是临时文件夹里,生成一个类似于hsperfdata_(userName)的文件夹(Linux中为/tmp/hsperfdata_{userName}/),该文件夹中有几个文件,名字就是java进程的pid;而jps命令列出当前运行的java进程,就是把这个目录里的文件名列一下而已。 至于系统的参数什么,可以通过解析这几个文件获得。
deploy@127.0.0.1:~$ cd /tmp/hsperfdata_deploy/
deploy@127.0.0.1:/tmp/hsperfdata_deploy$ ll
total 64
-rw------- 1 deploy deploy 32768 May 26 17:24 27075
-rw------- 1 deploy deploy 32768 May 26 17:24 3875
可以看到,进程号就是上面我们所展示的。
4.注意事项
注意,jps仅查找当前用户的Java进程,而不是当前系统中的所有进程,所以查询的时候需要注意用户的相关权限。
本文参考自(链接中包含了jps失效及更多有关jps的内容,大家都可以进行参考):
https://www.hollischuang.com/archives/105
Jps无法查看运行程序进程
二、jinfo命令
1. 介绍
jinfo(Java Configuration Info),是Java自带的命令,用于实时查看和调整Java应用程序的配置参数,其中配置参数包含两部分,其中只能查看的是Java系统属性,既能查看又能调整的是JVM参数;并且,当系统崩溃时,jinfo可以从core文件里面知道崩溃的Java应用程序的配置信息。
deploy@127.0.0.1:~$ jinfo -help
Usage:
jinfo [option] <pid>
(to connect to running process)
jinfo [option] <executable <core>
(to connect to a core file)
jinfo [option] [server_id@]<remote server IP or hostname>
(to connect to remote debug server)
where <option> is one of:
-flag <name> to print the value of the named VM flag
-flag [+|-]<name> to enable or disable the named VM flag
-flag <name>=<value> to set the named VM flag to the given value
-flags to print VM flags
-sysprops to print Java system properties
<no option> to print both of the above
-h | -help to print this help message
deploy@127.0.0.1:~$
我们来简单看下它的操作格式:
jinfo [option] <pid> 进程id
jinfo [option] <executable <core> 生成core dump文件
jinfo [option] [server_id@] ... 连接远程机器操作
其中,参数option我们可以直接看上面的注释,比较简单,这里简单解释下:
[option]
<no option> 默认情况下,会展示全部的JVM参数和Java系统属性
-flag <name> 查看对应名称的JVM参数
-flag [+|-]<name> 对布尔类型的JVM配置进行开启或关闭
-flag <name>=<value> 设置对应的JVM配置
-flags 展示全部JVM参数
-sysprops 展示Java系统属性
-h | -help 展示帮助信息
2. 使用
我们在服务器上进行简单操作下:
1)先看下最简单的方式,jinfo pid
:
deploy@127.0.0.1:~$ jinfo 20995
Attaching to process ID 20995, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.66-b17
Java System Properties:
com.sun.management.jmxremote.authenticate = false
java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.66-b17
sun.boot.library.path = /usr/java/jdk1.8.0_66/jre/lib/amd64
java.vendor.url = http://java.oracle.com/
java.vm.vendor = Oracle Corporation
path.separator = :
java.rmi.server.randomIDs = true
file.encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
sun.os.patch.level = unknown
sun.java.launcher = SUN_STANDARD
user.country = US
...
VM Flags:
Non-default VM flags: -XX:CICompilerCount=4 -XX:CMSFullGCsBeforeCompaction=0
-XX:CMSInitiatingOccupancyFraction=62 -XX:CMSTriggerRatio=70
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=null
-XX:InitialHeapSize=536870912 -XX:+ManagementServer
-XX:MaxHeapSize=536870912 -XX:MaxMetaspaceSize=67108864
...
Command line: -Xms512m -Xmx512m -Xmn256m -XX:MaxMetaspaceSize=64m
-XX:MetaspaceSize=64m -Dfile.encoding=UTF-8 -XX:+UseConcMarkSweepGC
-XX:+UseParNewGC -XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0 -XX:CMSInitiatingOccupancyFraction=62
-XX:CMSTriggerRatio=70
...
这里展示的信息太多,省略了大部分数据;不过可以看到,展示的数据总体上是分两部分的,一部分是Java System Properties:
,另一部分是VM Flags:
,
2)接下来我们看下 展示指定的JVM参数的值:
deploy@127.0.0.1:~$ jinfo -flag MaxNewSize 20995
-XX:MaxNewSize=268435456
3)JVM参数的调整,如果是布尔类型的,使用 jinfo -flag [+|-]<name> PID
,其中 +
表示开启,-
表示关闭操作;而如果是字符串或者数字类型,使用 jinfo -flag <name>=<value>
,这里就不多演示了;
4)jinfo虽然可以在java程序运行时动态地修改JVM参数,但并不是所有的参数都支持动态修改,而哪些参数支持jinfo动态修改呢?在官方文档中有一段这样的描述:
Flags marked as manageable are dynamically writeable through the JDK management interface (com.sun.management.HotSpotDiagnosticMXBean API) and also through JConsole.
也就是说,通过com.sun.management.HotSpotDiagnosticMXBean 这个类的接口得到的参数,或者是标记为manageable的参数菜可以支持动态修改。首先,我们来看下标记为manageable的Flags,我们可以通过如下命令查看:
Linux环境: java -XX:+PrintFlagsInitial | grep manageable
Window环境:java -XX:+PrintFlagsInitial | findstr manageable
运行后获取到的数据如下:
deploy@127.0.0.1:~$ java -XX:+PrintFlagsInitial | grep manageable
intx CMSAbortablePrecleanWaitMillis = 100 {manageable}
intx CMSTriggerInterval = -1 {manageable}
intx CMSWaitDuration = 2000 {manageable}
bool HeapDumpAfterFullGC = false {manageable}
bool HeapDumpBeforeFullGC = false {manageable}
bool HeapDumpOnOutOfMemoryError = false {manageable}
ccstr HeapDumpPath = {manageable}
uintx MaxHeapFreeRatio = 70 {manageable}
uintx MinHeapFreeRatio = 40 {manageable}
bool PrintClassHistogram = false {manageable}
bool PrintClassHistogramAfterFullGC = false {manageable}
bool PrintClassHistogramBeforeFullGC = false {manageable}
bool PrintConcurrentLocks = false {manageable}
bool PrintGC = false {manageable}
bool PrintGCDateStamps = false {manageable}
bool PrintGCDetails = false {manageable}
bool PrintGCID = false {manageable}
bool PrintGCTimeStamps = false {manageable}
deploy@127.0.0.1:~$
备注:为了展示,格式做了简单调整。
另外,我们也可以通过代码来实现,方式是通过 通过HotSpotDiagnosticMXBean API,查看该类的 Java Doc,有一个getDiagnosticOptions()这样的方法,该方法的详细描述如下:
Returns a list of VMOption objects for all diagnostic options. A diagnostic option is a writeable VM option that can be set dynamically mainly for troubleshooting and diagnosis.
接下来通过Java代码调用该API得到所有可动态修改的JVM参数, java代码如下:
/**
* @author afei
* @version 1.0.0
* @since 2017年07月25日
*/
public class DiagnosticOptionsTest {
public static void main(String[] args) {
HotSpotDiagnostic mxBean = new HotSpotDiagnostic();
List<VMOption> diagnosticVMOptions = mxBean.getDiagnosticOptions();
for (VMOption vmOption:diagnosticVMOptions){
System.out.println(vmOption.getName() + " = " + vmOption.getValue());
}
}
}
结果的话,大家跑一下程序就知道了,可以看到和Linux命令操作是一样的结果。
备注:由于HotSpotDiagnosticMXBean 是接口(public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean ),所以需要通过它唯一的实现类HotSpotDiagnostic 来调用这个方法。
3. 总结
jinfo命令比较简单,使用该命令可以让我们在不重启JVM的情况下动态的修改JVM的参数,这点对我们来说有时候有些时候还是挺有用的。
本文最后部分来自阿飞哥的博客,博客地址:
阿飞的博客 - 简书 - jinfo命令详解