JVM 命令行监控工具详解

JVM 命令行监控工具

①.jinfo  【显示jvm虚拟机的配置信息】

我们先来查下文档jinfo的用法

使用命令man -jinfo查看用户手册

NAME
       jinfo - configuration info

SYNOPSIS
       jinfo [ option ] pid
       jinfo [ option ] executable core
       jinfo [ option ] [ server-id@ ] remote-hostname-or-IP

PARAMETERS
       Options are mutually exclusive. Option, if used, should follow immediately after the command name. See OPTIONS below.

       pid            process  id  for which the configuration info is to be printed. The process must be a Java process. To get a
                      list of Java processes running on a machine, jps many be used.

       executable     Java executable from which the core dump was produced.

       core           core file for which the configuration info is to be printed.

       remote-hostname-or-IP
                      remote debug server's (see jsadebugd) hostname or IP address.

       server-id      optional unique id, if multiple debug servers are running on the same remote host.

DESCRIPTION
       jinfo prints Java configuration information for a given Java process or core file or a remote debug server.   Configuration
       information includes Java System properties and Java virtual machine command line flags.

       NOTE  -  This utility is unsupported and may or may not be available in future versions of the J2SE SDK.  jinfo is not cur-
       rently available on Windows platforms or on the Linux Itanium platform.

OPTIONS
        <no option>   prints both command line flags as well as System properties name, value pairs

       -flags         prints command line flags as name, value pairs

       -sysprops      prints JavaSystem properties as name, value pairs

由手册可知,jinfo命令必须指明运行虚拟机进程(Java进程)的pid号,那么我们怎样得知我们的程序运行的pid呢?有两种办法:

  1. 使用lsof -i:端口号(例如lsof -i:8081)
    jianlejundeMBP:~ allan$ lsof -i:8081
    COMMAND   PID  USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
    STS     25301 allan   76u  IPv6 0x7664412dd30e5b9d      0t0  TCP localhost:58969->localhost:sunproxyadmin (CLOSE_WAIT)
    java    31978 allan   52u  IPv6 0x7664412dc6198e1d      0t0  TCP *:sunproxyadmin (LISTEN)

    这里明显pid为31978的进程即为我们所需要的应用程序pid号

  2. 使用jvm的命令jps,列出所有使用虚拟机的进程(直接jps或者加个参数 -l )
    jianlejundeMBP:~ allan$ jps -l
    pid   启动的主类名
    25301 
    31978 org.apache.catalina.startup.Bootstrap
    32266 sun.tools.jps.Jps

    由上可知,31978的pid为我们所需要的进程(Bootstrap为tomcat的启动入口)

获取到Java进程号后,我们接下来分析jinfo的可选参数

  • jinfo pid,则会同时列出jvm系统的属性信息和配置信息
  • jinfo -flags pid 则只列出配置信息(****)
jianlejundeMBP:~ allan$ jinfo -flags 31978
Attaching to process ID 31978, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.141-b15

**************重点关注************
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=134217728 -XX:MaxHeapSize=268435456 -XX:MaxNewSize=67108864 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=67108864 -XX:OldSize=67108864 -XX:ThreadStackSize=32768 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC 

**************重点关注************
Command line:  -Xmx256m -Xms128m -Xmn64m -Xss32m -Dcatalina.base=/Users/allan/Documents/STSworkspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0 -Dcatalina.home=/Users/allan/Documents/tomcat_CRM_trunk/apache-tomcat-8.5.16 -Dwtp.deploy=/Users/allan/Documents/STSworkspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps -Djava.endorsed.dirs=/Users/allan/Documents/tomcat_CRM_trunk/apache-tomcat-8.5.16/endorsed -Dfile.encoding=UTF-8
  • jinfo -sysprops pid 将虚拟机进程的System.getProperties()信息打印出来(了解即可)
  • jinfo -flag 属性名 pid:获取指定jdk参数名的值(例如 jinfo -flag InitialHeapSize 31978,结果为134217728)
  • jinfo -flag  name=value pid修改jvm在运行时可以修改的部分参数(jinfo -flag MaxHeapFreeRatio=99 31978)(了解即可)

查看jvm运行时可以动态修改的参数

$ java -XX:+PrintFlagsFinal | grep manageable

② jps【列出所有正在运行的虚拟机进程】

jps -l  输出pid和该进程的启动主类名

jianlejundeMBP:~ allan$ jps -l
33232 org.apache.catalina.startup.Bootstrap
32467 
33339 sun.tools.jps.Jps

jps -v 输出jvm启动时的JVM参数

③jstat(监视虚拟机各种运行状态信息,运行期间定位性能问题的首选工具)

他可以显示本地或者远程虚拟机中的类装载、卸载数量、内存、垃圾收集、JIT编译状况等运行时数据。

命令格式:jstat [option vmid [interval [s|ms] [count]]

其中option,vmid为必要项,后面的为可选项,interval表示查询间隔时间(默认单位为毫秒),count表示查询次数,如果省略可选项表示查询一次。

如果想要每隔250毫秒查询一次java堆状况,一共查询10次,命令:jstat -gc 33232 250 10

如果想要每隔2秒查询一次java堆状况,一共查询5次,命令:jstat -gc 33232 2s 5

以下S0指FromSurvivor区,S1指ToSuvivor区

 

jstat可选参数
选项作用示例
-class监视类装载卸载数量、总时间等

jianlejundeMBP:~ allan$ jstat -class 33232

Loaded  Bytes  Unloaded  Bytes     Time   

  5586 11087.5        0     0.0       4.10

1.类装载数量 2.类的总大小(字节) 3.类卸载数 4.大小 5.类装载所耗费的时间
-gc监视堆状况

jianlejundeMBP:~ allan$ jstat -gc 33232

S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   

512.0  512.0  256.0   0.0   64512.0   9040.7   73216.0    19884.9   34608.0 33736.6 4144.0 3904.5    356    0.703   1      0.051    0.754

S0C:S0分配的容量(字节)/ S0U:S0已经使用的空间(字节) /EC:Eden区分配的容量/EU:Eden已使用 /OC:老年代容量 /OU:老年代已使用空间/MC:方法区大小分配的容量/CCSC:压缩类空间大小/YGC:程序运行以来共运行MinorGC次数/YGCT:运行MinorGC总耗时

/FGC:程序运行以来共运行MajorGC次数/GCT:所有GC操作总耗时

 

-gccapacity

显示Java堆各个区域的最大、最小空间

jianlejundeMBP:~ allan$ jstat -gccapacity 33232

NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC

65536.0  65536.0  65536.0  512.0  512.0  64512.0    65536.0   196608.0    73216.0    73216.0      0.0 1079296.0  34608.0      0.0 1048576.0   4144.0    518     1

NGCMN:新生代分配的最小可用空间/NGCMX:新生代分配的最小可用空间 NGCMX/NGC:当前新生代容量/MCMN:最小元数据容量

/MC:当前元数据空间大小/CCSMN:最小压缩类空间大小

-gcutil显示各个区域已使用空间所占百分比

jianlejundeMBP:~ allan$ jstat -gcutil 33232

  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   

  0.00  50.00  50.00  27.30  97.57  94.22    633    1.128     1    0.051    1.178

-gccause与gcutil基本一致,还显示多一条导致上一次GC的原因

jianlejundeMBP:~ allan$ jstat -gccause 33232

  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC                 

43.75   0.00  40.01  27.30  97.59  94.22    644    1.143     1    0.051    1.194 Allocation Failure   No GC       

-complier输出JIT编译器编译过的方法、耗时等信息

zhoudadadeMBP:~ shoje$ jstat -compiler 33232

Compiled Failed Invalid   Time   FailedType FailedMethod

    3894      1       0    24.11          1 org/apache/tomcat/util/IntrospectionUtils setProperty

   

 


④ jmap (内存映像工具)

主要用于生成堆转储快照,生成dump文件或称为heapdump文件,同时可以查询java堆和永久代的详细信息,如空间使用率,是使用哪种收集器等)

查询手册如下:

NAME
       jmap - memory map

SYNOPSIS
       jmap [ option ] pid
       jmap [ option ] executable core
       jmap [ option ] [ server-id@ ] remote-hostname-or-IP

DESCRIPTION
       jmap prints shared object memory maps or heap memory details of a given process or core file or remote debug server.

       NOTE  -  This  utility  is unsupported and may or may not be available in future versions of the J2SE SDK.  jmap is not currently available on Windows platforms or on the Linux
       Itanium platform.

PARAMETERS
       option         Options are mutually exclusive. Option, if used, shouldfollow immediately after the command name.

       pid            process id for which the memory map is to be printed.  The process must be a Java process. To get a list of Java processes running on a machine, jps may be used.

       executable     Java executable from which the core dump was produced.

       core           core file for which the memory map is to be printed.

       remote-hostname-or-IP
                      remote debug server's (see jsadebugd) hostname or IP address.

       server-id      optional unique id, if multiple debug servers are running on the same remote host.

OPTIONS
        <no option>   When  no  option is used jmap prints shared object mappings. For each shared object loaded in the target VM, start address, the size of the mapping, and the full
                      path of the shared object file are printed. This is similar to the Solaris pmap utility.
       -dump:<dump-options> to dump java heap in hprof binary format
                         dump-options:
                           live         dump only live objects; if not specified,
                                        all objects in the heap are dumped.
                           format=b     binary format
                           file=<file>  dump heap to <file>

       -heap          Prints a heap summary. GC algorithm used, heap configuration and generation wise heap usage are printed.

       -histo         Prints a histogram of the heap. For each Java class, number of objects, memory size in bytes, and fully qualified class names  are  printed.  VM  internal  class
                      names are printed with '*' prefix.

       -permstat      Prints class loader wise statistics of permanent generation of Java heap. For each class loader, its name, liveness, address, parent class loader, and the number
                      and size of classes it has loaded are printed.

       -h             Prints a help message.

       -help          Prints a help message.

SEE ALSO
       pmap(1) jps(1) jsadebugd(1)

jmap的option为可选项,但不接可选项时基本得到的结果参考价值不大,我们这里主要关注三个选项,-heap,-dump,-histo

1.jmap -heap pid

jianlejundeMBP:~ allan$ jmap -heap 35133
Attaching to process ID 35133, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.141-b15(虚拟机版本)

using thread-local object allocation.
Parallel GC with 4 thread(s)(使用何种收集器)

Heap Configuration:(Java堆的配置信息)
   MinHeapFreeRatio         = 0 (堆使用率小于n时进行收缩)
   MaxHeapFreeRatio         = 100 (堆使用率大于n时进行扩张,2个参数在Xmx==Xms 的情况下无效)
   MaxHeapSize              = 268435456 (256.0MB) (最大堆可用空间)
   NewSize                  = 67108864 (64.0MB)  (新生代空间大小)
   MaxNewSize               = 67108864 (64.0MB)   (新生代最大可用空间)
   OldSize                  = 67108864 (64.0MB)   (老年代可用空间)
   NewRatio                 = 2(设置老年代与新生代的比例,OLD/NEW=2)
   SurvivorRatio            = 8(设置Eden:S1:S2=8:1:1,这是jvm的默认设置)
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:(堆的内存监控信息)
PS Young Generation
Eden Space:
   capacity = 66060288 (63.0MB) (可用空间)
   used     = 22447528 (21.407630920410156MB) (已使用)
   free     = 43612760 (41.592369079589844MB) (空闲)
   33.980366540333584% used  (已使用所占的百分比)
From Space:
   capacity = 524288 (0.5MB)
   used     = 262144 (0.25MB)
   free     = 262144 (0.25MB)
   50.0% used
To Space:
   capacity = 524288 (0.5MB)
   used     = 0 (0.0MB)
   free     = 524288 (0.5MB)
   0.0% used
PS Old Generation
   capacity = 77594624 (74.0MB)
   used     = 17072000 (16.2811279296875MB)
   free     = 60522624 (57.7188720703125MB)
   22.00152422930743% used

17747 interned Strings occupying 2199536 bytes.

有上可知,jmap -heap可以获取堆的一些启动参数和内存映像信息以及使用的垃圾收集器

2.jmap -dump[:live,]format=b,file=filename pid

jianlejundeMBP:~ allan$ jmap -dump:live,format=b,file=Documents/mydumpfile.bin 35133
Dumping heap to /Users/shoje/Documents/mydumpfile.bin ...
Heap dump file created

命令的含义为导出jvm的java堆所有存活对象dump文件,以二进制形式输出,拿到这个这个文件后就可以借助外部的可视化监控工具或者其他途径进行堆的分析。

3.jmap -histo:live pid(显示堆中对象统计信息,包括类,实例数据、实例数量、合计容量等)

作为演示,只截取部分信息

num     #instances         #bytes  class name
----------------------------------------------
   1:         52125        8561888  [C
   2:         50953        1222872  java.lang.String
   3:          1070         760600  [B
   4:          8022         705936  java.lang.reflect.Method
   5:          6084         683624  java.lang.Class
   6:         15582         498624  java.util.HashMap$Node
   7:         13256         424192  java.util.concurrent.ConcurrentHashMap$Node
   8:          6271         376712  [Ljava.lang.Object;
   9:          1789         233008  [Ljava.util.HashMap$Node;
  10:          6766         216512  java.lang.ref.WeakReference
  11:          3658         146320  java.lang.ref.SoftReference
  12:          3326         133040  java.util.LinkedHashMap$Entry
  13:          7725         123600  java.lang.Object
  14:          2790         115416  [Ljava.lang.String;
  15:          2757         112008  [I
  16:           118         102592  [Ljava.util.concurrent.ConcurrentHashMap$Node;
  17:          4041          96984  java.beans.MethodRef
  18:          1985          95280  java.util.HashMap
  19:          1607          89992  java.beans.MethodDescriptor
  20:          3589          86136  java.util.ArrayList
  21:          1499          83944  java.util.LinkedHashMap
        .
        .
        .
        .
        .
        .

由该结果可以很清晰的看出哪些实例的数据所占的空间过大。

4.jmap -finalizerinfo pid(显示在F-Queue等待的Finalizer线程执行finalizer方法的对象,了解即可)

⑤jstack(生成虚拟机的线程快照threaddump或javacore)

线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合

作用:生成线程快照的主要目的是定位线程长时间停顿的原因

语法:jstack [-option] pid

下面为使用jstack 35133命令的结果:(前面关于判断存活对象时涉及到Finalizer线程线程)

"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007fca55839000 nid=0x2e03 in Object.wait() [0x0000700001e04000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x0000000797bda188> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
	- locked <0x0000000797bda188> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
	at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)


"main" #1 prio=5 os_prio=31 tid=0x00007fca55806800 nid=0x2503 runnable [0x00007000016ee000]
   java.lang.Thread.State: RUNNABLE
	at java.net.PlainSocketImpl.socketAccept(Native Method)
	at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
	at java.net.ServerSocket.implAccept(ServerSocket.java:545)
	at java.net.ServerSocket.accept(ServerSocket.java:513)
	at org.apache.catalina.core.StandardServer.await(StandardServer.java:466)
	at org.apache.catalina.startup.Catalina.await(Catalina.java:744)
	at org.apache.catalina.startup.Catalina.start(Catalina.java:690)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:355)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:495)

"VM Thread" os_prio=31 tid=0x00007fca5600b000 nid=0x2c03 runnable 

"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007fca55009000 nid=0x2107 runnable 

"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007fca56003000 nid=0x2a03 runnable 

(java Thread类中增加了getAllStackTraces()方法用于获取虚拟机中所有的StackTraceElement对象)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值