JVMコマンドラインモニタツールの詳細

15983 ワード

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
           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をどのように知るかには、2つの方法があります.
  • 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番号
  • である.
  • jvmのコマンドjpsを使用して、仮想マシンを使用するすべてのプロセス(直接jpsまたはパラメータ-lを追加)
    jianlejundeMBP:~ allan$ jps -l
    pid         
    25301 
    31978 org.apache.catalina.startup.Bootstrap
    32266 sun.tools.jps.Jps
    をリストします.
    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はクエリー回数を表し,オプションを省略するとクエリーが1回を表す.
    250ミリ秒ごとにjavaスタックの状況をクエリーしたい場合は、合計10回クエリーします.コマンド:jstat-gc 33232 250 10
    Javaスタックの状況を2秒おきにクエリーしたい場合は、合計5回クエリーします.コマンド:jstat-gc 33232 2 s 5
    以下S 0はFromSurvivor領域、S 1は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
    S 0 C:S 0割り当て容量(バイト)/S 0 U:S 0使用済みスペース(バイト)/EC:Edenゾーン割り当て容量/EU:Eden使用済み/OC:旧世代容量/OU:旧世代使用スペース/MC:メソッドゾーンサイズ割り当て容量/CSC:圧縮クラススペースサイズ/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:現在のメタデータ空間サイズ/CSMN:最小圧縮クラス空間サイズ
    -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
               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: 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=  dump heap to 
    
           -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はオプションですが、オプションを受け取らないと基本的に得られる結果の参考価値は大きくありません.ここでは主に3つのオプションに注目します.-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クラスにgetalStackTraces()メソッドを追加して、仮想マシン内のすべてのStackTraceElementオブジェクトを取得します)