Java工具-jps/jinfo命令学习(二)

一、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 -qjps -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命令详解

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容