zoukankan      html  css  js  c++  java
  • JDK常用分析工具

    在JDK的bin目录下有很多命令行工具

    [root@iZ2ze1224b1em0jij7qlssZ bin]#  ls -lak|grep j
    -rwxr-xr-x 1 root root   7 Apr 18  2019 idlj
    -rwxr-xr-x 1 root root   7 Apr 18  2019 jar
    -rwxr-xr-x 1 root root   7 Apr 18  2019 jarsigner
    -rwxr-xr-x 1 root root   7 Apr 18  2019 java
    -rwxr-xr-x 1 root root   7 Apr 18  2019 javac
    -rwxr-xr-x 1 root root   7 Apr 18  2019 javadoc
    -rwxr-xr-x 1 root root   7 Apr 18  2019 javah
    -rwxr-xr-x 1 root root   7 Apr 18  2019 javap
    -rwxr-xr-x 1 root root   3 Apr 18  2019 java-rmi.cgi
    -rwxr-xr-x 1 root root   7 Apr 18  2019 jcmd
    -rwxr-xr-x 1 root root   7 Apr 18  2019 jconsole
    -rwxr-xr-x 1 root root   7 Apr 18  2019 jdb
    -rwxr-xr-x 1 root root   7 Apr 18  2019 jdeps
    -rwxr-xr-x 1 root root   7 Apr 18  2019 jhat
    -rwxr-xr-x 1 root root   7 Apr 18  2019 jinfo
    -rwxr-xr-x 1 root root   7 Apr 18  2019 jjs
    -rwxr-xr-x 1 root root   7 Apr 18  2019 jmap
    -rwxr-xr-x 1 root root   7 Apr 18  2019 jps
    -rwxr-xr-x 1 root root   7 Apr 18  2019 jrunscript
    -rwxr-xr-x 1 root root   7 Apr 18  2019 jsadebugd
    -rwxr-xr-x 1 root root   7 Apr 18  2019 jstack
    -rwxr-xr-x 1 root root   7 Apr 18  2019 jstat
    -rwxr-xr-x 1 root root   7 Apr 18  2019 jstatd
    -rwxr-xr-x 1 root root   7 Apr 18  2019 xjc

    可以看到各个工具的大小基本上都稳定在7k左右,这个不是JDK开发团队刻意为之的,而是因为这些工具大多数是jdklib ools.jar类库的一层薄包装而已,他们的主要功能代码是在tools类库中实现的。命令行工具的好处是:当应用程序部署到生产环境后,无论是直接接触物理服务器还是远程telnet到服务器上都会受到限制。而借助tools.jar类库里面的接口,我们可以直接在应用程序中实现功能强大的监控分析功能。

    这里主要介绍如下几个工具:

      1、jps:查看本机java进程信息

      2、jstack:打印线程的信息,制作 线程dump文件

      3、jmap:打印内存映射信息,制作 堆dump文件

      4、jstat:性能监控工具

      5、jhat:内存分析工具,用于解析堆dump文件并以适合人阅读的方式展示出来

      6、jconsole:简易的JVM可视化工具

      7、jvisualvm:功能更强大的JVM可视化工具

    JAVA Dump:

    JAVA Dump就是虚拟机运行时的快照,将虚拟机运行时的状态和信息保存到文件中,包括:

    线程dump:包含所有线程的运行状态,纯文本格式

    堆dump:包含所有堆对象的状态,二进制格式

    1、jps

    显示当前所有java进程pid的命令,我们可以通过这个命令来查看到底启动了几个java进程(因为每一个java程序都会独占一个java虚拟机实例),不过jps有个缺点是只能显示当前用户的进程id,要显示其他用户的还只能用linux的ps命令。

    [root@iZ2ze1224b1em0jij7qlssZ bin]# jps
    25699 jar
    10947 jar
    26949 QuorumPeerMain
    25350 jar
    22696 jar
    21993 jar
    7337 jar
    3241 jar
    5130 jar
    10220 jar

     执行jps命令,会列出所有正在运行的java进程,其中jps命令也是一个java程序。前面的数字就是进程的id。

    jps -help:

    [root@iZ2ze1224b1em0jij7qlssZ bin]# jps -help
    usage: jps [-help]
           jps [-q] [-mlvV] [<hostid>]
    
    Definitions:
        <hostid>:      <hostname>[:<port>]

    jps -l :输出应用程序main.class的完整package名或者应用程序jar文件完整路径名。

    [root@iZ2ze1224b1em0jij7qlssZ bin]# jps -l10220 inner-0.0.1-SNAPSHOT.jar
    2860 org.apache.catalina.startup.Bootstrap2897 org.apache.catalina.startup.Bootstrap2774 org.apache.catalina.startup.Bootstrap
    26488 org.apache.catalina.startup.Bootstrap16764 sun.tools.jps.Jps
    7965 org.apache.catalina.startup.Bootstrap
    2078 maintenancekey-server.jar

    jps -v 输出传递给JVM的参数

    [root@iZ2ze1224b1em0jij7qlssZ bin]# jps -v
    25699 jar
    10947 jar
    26949 QuorumPeerMain -Dzookeeper.log.dir=. -Dzookeeper.root.logger=INFO,CONSOLE -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false
    25350 jar
    22696 jar
    21993 jar
    7337 jar
    3241 jar
    5130 jar
    10220 jar

    jps失效

    我们在定位问题过程会遇到这样一种情况,用jps查看不到进程id,用ps -ef | grep java却能看到启动的java进程。

    要解释这种现象,先来了解下jps的实现机制:

    java程序启动后,会在目录/tmp/hsperfdata_{userName}/下生成几个文件,文件名就是java进程的pid,因此jps列出进程id就是把这个目录下的文件名列一下而已,至于系统参数,则是读取文件中的内容。

    我们来思考下:如果由于磁盘满了,无法创建这些文件,或者用户对这些文件没有读的权限。又或者因为某种原因这些文件或者目录被清除,出现以上这些情况,就会导致jps命令失效。

    如果jps命令失效,而我们又要获取pid,还可以使用以下两种方法:

    1、top | grep java
    2、ps -ef |grep java

    2、jstack

    用于生成指定进程当前时刻的线程快照,线程快照是当前java虚拟机每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致长时间等待。

    [root@iZ2ze1224b1em0jij7qlssZ bin]# jstack 2078
    2021-07-14 13:33:27
    Full thread dump OpenJDK 64-Bit Server VM (25.212-b04 mixed mode):
    
    "Attach Listener" #526 daemon prio=9 os_prio=0 tid=0x00007f07b000b000 nid=0x4a63 runnable [0x0000000000000000]
       java.lang.Thread.State: RUNNABLE
    
    "http-nio-8501-exec-79" #382 daemon prio=5 os_prio=0 tid=0x00007f079004f000 nid=0x279d waiting on condition [0x00007f078f9fc000]
       java.lang.Thread.State: WAITING (parking)
            at sun.misc.Unsafe.park(Native Method)
            - parking to wait for  <0x00000006c6100118> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
            at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
            at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
            at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
            at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
            at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
            at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
            at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
            at java.lang.Thread.run(Thread.java:748)

    3、jmap

    用于打印指定java进程的共享对象内存映射或堆内存细节。

    堆Dump是反映堆使用情况的内存镜像,其中主要包括系统信息、虚拟机属性、完整的线程Dump、所有类和对象的状态等。一般在内存不足,GC异常等情况下,我们会去怀疑内存泄漏,这个时候就会去打印堆Dump。

    [root@iZ2ze1224b1em0jij7qlssZ bin]# jmap -h
    Usage:
        jmap [option] <pid>
            (to connect to running process)
        jmap [option] <executable <core>
            (to connect to a core file)
        jmap [option] [server_id@]<remote server IP or hostname>
            (to connect to remote debug server)
    
    where <option> is one of:
        <none>               to print same info as Solaris pmap
        -heap                to print java heap summary
        -histo[:live]        to print histogram of java object heap; if the "live"
                             suboption is specified, only count live objects
        -clstats             to print class loader statistics
        -finalizerinfo       to print information on objects awaiting finalization
        -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>
                             Example: jmap -dump:live,format=b,file=heap.bin <pid>
        -F                   force. Use with -dump:<dump-options> <pid> or -histo
                             to force a heap dump or histogram when <pid> does not
                             respond. The "live" suboption is not supported
                             in this mode.
        -h | -help           to print this help message
        -J<flag>             to pass <flag> directly to the runtime system

    1)、jmap pid

    [root@iZ2ze1224b1em0jij7qlssZ bin]# jmap 25699 
    Attaching to process ID 25699, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.212-b04
    0x0000000000400000      6K      /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/bin/java
    0x00007fd39d4bb000      108K    /lib64/libresolv-2.12.so
    0x00007fd39d6d5000      27K     /lib64/libnss_dns-2.12.so
    0x00007fd3e6237000      466K    /lib64/libfreeblpriv3.so
    0x00007fd3e64b0000      242K    /lib64/libnspr4.so
    0x00007fd3e66ef000      18K     /lib64/libplc4.so
    0x00007fd3e68f4000      14K     /lib64/libplds4.so
    0x00007fd3e6af8000      187K    /usr/lib64/libnssutil3.so
    0x00007fd3e6d27000      1305K   /usr/lib64/libnss3.so
    0x00007fd3e706f000      181K    /usr/lib64/libsmime3.so
    0x00007fd3e729c000      328K    /usr/lib64/libssl3.so
    0x00007fd3e74ef000      46K     /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/amd64/libsunec.so
    0x00007fd3ec63c000      71K     /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/amd64/libnio.so
    0x00007fd3ec84e000      38K     /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/amd64/libmanagement.so
    0x00007fd3ecd58000      94K     /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/amd64/libnet.so
    0x00007fd3ff7ad000      34K     /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/amd64/libzip.so
    0x00007fd3ff9b6000      64K     /lib64/libnss_files-2.12.so
    0x00007fd3ffbc4000      175K    /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/amd64/libjava.so
    0x00007fd3ffdf0000      62K     /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/amd64/libverify.so
    0x00007fd4040f0000      43K     /lib64/librt-2.12.so
    0x00007fd4042f8000      88K     /lib64/libgcc_s-4.4.7-20120601.so.1
    0x00007fd40450e000      582K    /lib64/libm-2.12.so
    0x00007fd404792000      963K    /usr/lib64/libstdc++.so.6.0.13
    0x00007fd404a98000      14352K  /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/amd64/server/libjvm.so
    0x00007fd405abf000      1879K   /lib64/libc-2.12.so
    0x00007fd405e53000      19K     /lib64/libdl-2.12.so
    0x00007fd406057000      58K     /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/amd64/jli/libjli.so
    0x00007fd406266000      86K     /lib64/libz.so.1.2.3
    0x00007fd40647c000      139K    /lib64/libpthread-2.12.so
    0x00007fd406699000      155K    /lib64/ld-2.12.so

    打印的信息分别为:共享对象的起始地址、映射大小、共享对象路径的全程。

    2)、jmap -heap pid:查看堆使用情况

    [root@iZ2ze1224b1em0jij7qlssZ bin]# jmap -heap 25699 
    Attaching to process ID 25699, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.212-b04
    
    using thread-local object allocation.
    Parallel GC with 2 thread(s)
    
    Heap Configuration:
       MinHeapFreeRatio         = 0
       MaxHeapFreeRatio         = 100
       MaxHeapSize              = 4217372672 (4022.0MB)
       NewSize                  = 88080384 (84.0MB)
       MaxNewSize               = 1405616128 (1340.5MB)
       OldSize                  = 176160768 (168.0MB)
       NewRatio                 = 2
       SurvivorRatio            = 8
       MetaspaceSize            = 21807104 (20.796875MB)
       CompressedClassSpaceSize = 1073741824 (1024.0MB)
       MaxMetaspaceSize         = 17592186044415 MB
       G1HeapRegionSize         = 0 (0.0MB)
    
    Heap Usage:
    PS Young Generation
    Eden Space:
       capacity = 637534208 (608.0MB)
       used     = 326762024 (311.62454986572266MB)
       free     = 310772184 (296.37545013427734MB)
       51.25403780686228% used
    From Space:
       capacity = 524288 (0.5MB)
       used     = 116368 (0.1109771728515625MB)
       free     = 407920 (0.3890228271484375MB)
       22.1954345703125% used
    To Space:
       capacity = 524288 (0.5MB)
       used     = 0 (0.0MB)
       free     = 524288 (0.5MB)
       0.0% used
    PS Old Generation
       capacity = 238551040 (227.5MB)
       used     = 59055768 (56.319969177246094MB)
       free     = 179495272 (171.1800308227539MB)
       24.7560304075807% used
    
    11561 interned Strings occupying 978776 bytes.

    3)、jmap -histo pid:查看堆中对象数量和大小

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jmap -histo 25699
     num     #instances         #bytes  class name
    ----------------------------------------------
       1:       4134436       99226464  java.util.ArrayList
       2:       2062243       65991776  java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
       3:       2055722       65783104  java.util.concurrent.FutureTask
       4:       2055802       49339248  java.util.concurrent.LinkedBlockingQueue$Node
       5:        916752       36670080  com.miu360.area.LatLng
       6:       2055722       32891552  com.miu360.taxi.location.module.CoreThread$InsertDevicesRunnable$1
       7:         10615       25663720  [I
       8:         15012        5289088  [Ljava.lang.Object;
       9:         79300        5276104  [C
      10:         28175        3322512  [B
      11:         62512        1500288  java.lang.String
      12:         22163         886520  sun.nio.cs.UTF_8$Decoder

    打印的信息分别是:序列号、对象的数量、这些对象的内存占用大小、这些对象所属的类的全限定名

    如果是内部类,类名的开头会加上*,如果加上live子参数的话,如jmap -histo:live pid,这个命名会触发一次FUll GC,只统计存活对象

    4)、jmap -dump:format=b,file=heapdump pid:将内存使用的详细情况输出到文件

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jmap -dump:format=b,file=heapdump 25699
    Dumping heap to /opt/heapdump ...
    Heap dump file created

         然后使用jhat命令查看该文件:jhat -port 4000 文件名 ,在浏览器中访问http:localhost:4000/

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jhat -port 4000 heapdump 
    Reading from heapdump...
    Dump file created Wed Jul 14 13:45:56 CST 2021
    Snapshot read, resolving...
    Resolving 1630999 objects...
    Chasing references, expect 326 dots......................................................................................................................................................................................................................................................................................................................................
    Eliminating duplicate references......................................................................................................................................................................................................................................................................................................................................
    Snapshot resolved.
    Started HTTP server on port 4000
    Server is ready.

    总结:

    该命令适用的场景是程序内存不足或者GC频繁,这时候很可能是内存泄漏。通过用以上命令查看堆使用情况、大量对象被持续引用等情况。

    4、jstat

    主要是对java应用程序的资源和性能进行实时的命令行监控,包括了对heap size和垃圾回收状况的监控。

     jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

    option:我们经常使用的选项有gc、gcutil

    vmid:java进程id

    interval:间隔时间,单位为毫秒

    count:打印次数

    1)、jstat -gc PID 5000 20 :垃圾回收统计

    5秒钟打印一次,一共打印20次。

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jstat -gc 25699 5000 20
     S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
    512.0  512.0   0.0    0.0   623104.0 72399.2   228352.0   48528.4   28800.0 28049.9 2944.0 2763.6  23000   65.580   3      0.365   65.945
    512.0  512.0   0.0    0.0   623104.0 72399.2   228352.0   48528.4   28800.0 28049.9 2944.0 2763.6  23000   65.580   3      0.365   65.945
    512.0  512.0   0.0    0.0   623104.0 72399.2   228352.0   48528.4   28800.0 28049.9 2944.0 2763.6  23000   65.580   3      0.365   65.945

    S0C:年轻代第一个Survivor区的大小(字节)
    S1C:年轻代第二个Survivor区的大小(字节)
    S0U:年轻代第一个Survivor区的使用大小(字节)
    S1U:年轻代第二个Survivor区的使用大小(字节)
    EC:年轻代中Eden区的大小(字节)
    EU:年轻代中Eden区的使用大小(字节)
    OC:老年代大小(字节)
    OU:老年代使用大小(字节)
    MC:方法区大小(字节)
    MU:方法区使用大小(字节)
    CCSC:压缩类空间大小(字节)
    CCSU:压缩类空间使用大小(字节)
    YGC:年轻代垃圾回收次数
    YGCT:年轻代垃圾回收消耗时间
    FGC:老年代垃圾回收次数
    FGCT:老年代垃圾回收消耗时间
    GCT:垃圾回收消耗总时间

    ps:之前的PC 和PU 被MC MU取代了。(永久代)

    2)、jstat -gccapacity pid 5000 20 : 堆内存统计

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jstat -gccapacity  25699 5000 20
     NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC 
     86016.0 1372672.0 624128.0  512.0  512.0 623104.0   172032.0  2745856.0   228352.0   228352.0      0.0 1075200.0  28800.0      0.0 1048576.0   2944.0  23000     3
     86016.0 1372672.0 624128.0  512.0  512.0 623104.0   172032.0  2745856.0   228352.0   228352.0      0.0 1075200.0  28800.0      0.0 1048576.0   2944.0  23000     3
     86016.0 1372672.0 624128.0  512.0  512.0 623104.0   172032.0  2745856.0   228352.0   228352.0      0.0 1075200.0  28800.0      0.0 1048576.0   2944.0  23000     3

    NGCMN:新生代最小容量
    NGCMX:新生代最大容量
    NGC:当前新生代容量
    S0C:第一个Survivor区大小
    S1C:第二个Survivor区的大小
    EC:Eden区的大小
    OGCMN:老年代最小容量
    OGCMX:老年代最大容量
    OGC:当前老年代大小
    OC:当前老年代大小
    MCMN:最小元数据容量
    MCMX:最大元数据容量
    MC:当前元数据空间大小
    CCSMN:最小压缩类空间大小
    CCSMX:最大压缩类空间大小
    CCSC:当前压缩类空间大小
    YGC:年轻代gc次数
    FGC:老年代GC次数

    3)、jstat -gcnew pid 5000 20 : 新生代垃圾回收统计

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jstat -gcnew   25699 5000 20
     S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT  
     512.0  512.0    0.0    0.0 15  15  512.0 623104.0 276460.9  23000   65.580
     512.0  512.0    0.0    0.0 15  15  512.0 623104.0 276460.9  23000   65.580
     512.0  512.0    0.0    0.0 15  15  512.0 623104.0 276460.9  23000   65.580
     512.0  512.0    0.0    0.0 15  15  512.0 623104.0 276466.3  23000   65.580

    S0C: 第一个Survivor区大小
    S1C: 第二个Survivor区的大小
    S0U: 第一个Survivor区的使用大小
    S1U: 第二个Survivor区的使用大小
    TT: 对象在新生代存活的次数
    MTT: 对象在新生代存活的最大次数
    DSS: 期望的Survivor区大小
    EC: Eden区的大小
    EU: Eden区的使用大小
    YGC: 年轻代垃圾回收次数
    YGCT: 年轻代垃圾回收消耗时间

    4)、jstat -gcnewcapacity pid 5000 20 : 新生代内存统计

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jstat  -gcnewcapacity   25699 5000 20
      NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC      YGC   FGC 
       86016.0  1372672.0   624128.0 457216.0    512.0 457216.0    512.0  1371648.0   623104.0 23000     3
       86016.0  1372672.0   624128.0 457216.0    512.0 457216.0    512.0  1371648.0   623104.0 23000     3
       86016.0  1372672.0   624128.0 457216.0    512.0 457216.0    512.0  1371648.0   623104.0 23000     3

    NGCMN:新生代最小容量
    NGCMX:新生代最大容量
    NGC:当前新生代容量
    S0CMX:第一个Survivor区最大大小
    S0C:第一个Survivor区当前大小
    S1CMX:第二个Survivor区最大大小
    S1C:第二个Survivor区当前大小
    ECMX:Eden区最大大小
    EC:Eden区当前大小
    YGC:年轻代垃圾回收次数

    5)、jstat -gcold pid 5000 20 : 老年代垃圾回收统计

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jstat  -gcold  25699 5000 20
       MC       MU      CCSC     CCSU       OC          OU       YGC    FGC    FGCT     GCT   
     28800.0  28049.9   2944.0   2763.6    228352.0     48528.4  23000     3    0.365   65.945
     28800.0  28049.9   2944.0   2763.6    228352.0     48528.4  23000     3    0.365   65.945
     28800.0  28049.9   2944.0   2763.6    228352.0     48528.4  23000     3    0.365   65.945

    MC: 方法区大小
    MU: 方法区使用大小
    CCSC: 压缩类空间大小
    CCSU: 压缩类空间使用大小
    OC: 老年代大小
    OU: 老年代使用大小
    YGC: 年轻代垃圾回收次数
    FGC: 老年代垃圾回收次数
    FGCT: 老年代垃圾回收消耗时间
    GCT: 垃圾回收消耗总时间

    6)、jstat -gcoldcapacity pid 5000 20 : 老年代内存统计

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jstat  -gcoldcapacity   25699 5000 20
       OGCMN       OGCMX        OGC         OC       YGC   FGC    FGCT     GCT   
       172032.0   2745856.0    228352.0    228352.0 23000     3    0.365   65.945
       172032.0   2745856.0    228352.0    228352.0 23000     3    0.365   65.945
       172032.0   2745856.0    228352.0    228352.0 23000     3    0.365   65.945

    OGCMN: 老年代最小容量
    OGCMX: 老年代最大容量
    OGC: 当前老年代大小
    OC: 老年代大小
    YGC: 年轻代垃圾回收次数
    FGC: 老年代垃圾回收次数
    FGCT: 老年代垃圾回收消耗时间
    GCT: 垃圾回收消耗总时间

    7)、jstat -gcmetacapacity pid 5000 20 : 元数据空间统计

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jstat  -gcmetacapacity  25699 5000 20
       MCMN       MCMX        MC       CCSMN      CCSMX       CCSC     YGC   FGC    FGCT     GCT   
           0.0  1075200.0    28800.0        0.0  1048576.0     2944.0 23000     3    0.365   65.945
           0.0  1075200.0    28800.0        0.0  1048576.0     2944.0 23000     3    0.365   65.945
           0.0  1075200.0    28800.0        0.0  1048576.0     2944.0 23000     3    0.365   65.945

    MCMN:最小元数据容量
    MCMX:最大元数据容量
    MC:当前元数据空间大小
    CCSMN:最小压缩类空间大小
    CCSMX:最大压缩类空间大小
    CCSC:当前压缩类空间大小
    YGC:年轻代垃圾回收次数
    FGC:老年代垃圾回收次数
    FGCT:老年代垃圾回收消耗时间
    GCT:垃圾回收消耗总时间

    8)、jstat -gcutil PID 5000 20 :总结垃圾回收统计

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jstat -gcutil 25699 5000 20
      S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
      0.00   0.00  27.10  21.25  97.40  93.87  23000   65.580     3    0.365   65.945
      0.00   0.00  27.10  21.25  97.40  93.87  23000   65.580     3    0.365   65.945
      0.00   0.00  27.10  21.25  97.40  93.87  23000   65.580     3    0.365   65.945
      0.00   0.00  27.10  21.25  97.40  93.87  23000   65.580     3    0.365   65.945

    S0:第一个Servivor区当前使用比例
    S1:第二个Servivor区当前使用比例
    E:Eden区使用比例
    O:老年代使用比例
    M:元数据区使用比例
    CCS:压缩使用比例
    YGC:年轻代垃圾回收次数
    FGC:老年代垃圾回收次数
    FGCT:老年代垃圾回收消耗时间
    GCT:垃圾回收消耗总时间

    5、jhat

    主要用来解析java堆dump并启动一个web服务器,然后就可以在浏览器中查看堆的dump文件了。

    jhat heapdump

    这个命令将heapdump文件转换成html格式,并且启动一个http服务,默认端口为7000。在浏览器中访问 http:localhost:7000/ 就能打开页面

    如果端口冲突,可以使用以下命令指定端口:jhat -port 4000 heapdump

    6、jinfo

    jinfo可以用来查看正在运行的java运用程序的扩展参数,甚至支持在运行时动态地更改部分参数。

    基本使用语法如下: jinfo -< option > < pid > ,其中option可以为以下信息:

    -flag< name >: 打印指定java虚拟机的参数值

    -flag [+|-]< name >:设置或取消指定java虚拟机参数的布尔值

    -flag < name >=< value >:设置指定java虚拟机的参数的值

    查看当前的运行参数:

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jinfo 25699
    Attaching to process ID 25699, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.212-b04
    Java System Properties:
    
    java.runtime.name = OpenJDK Runtime Environment
    java.vm.version = 25.212-b04
    sun.boot.library.path = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/amd64
    java.vendor.url = http://java.oracle.com/
    java.vm.vendor = Oracle Corporation
    path.separator = :
    file.encoding.pkg = sun.io
    java.vm.name = OpenJDK 64-Bit Server VM
    sun.os.patch.level = unknown
    sun.java.launcher = SUN_STANDARD
    user.country = US
    user.dir = /var/server/TaxiLocationServer2
    java.vm.specification.name = Java Virtual Machine Specification
    java.runtime.version = 1.8.0_212-b04
    java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
    os.arch = amd64
    java.endorsed.dirs = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/endorsed
    java.io.tmpdir = /tmp
    line.separator = 
    
    java.vm.specification.vendor = Oracle Corporation
    os.name = Linux
    sun.jnu.encoding = UTF-8
    jetty.git.hash = d5fc0523cfa96bfebfbda19606cad384d772f04c
    java.library.path = /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
    java.specification.name = Java Platform API Specification
    java.class.version = 52.0
    sun.management.compiler = HotSpot 64-Bit Tiered Compilers
    os.version = 2.6.32-754.14.2.el6.x86_64
    user.home = /root
    user.timezone = Asia/Shanghai
    java.awt.printerjob = sun.print.PSPrinterJob
    file.encoding = UTF-8
    java.specification.version = 1.8
    user.name = root
    java.class.path = TaxiLocationServer2.jar
    java.vm.specification.version = 1.8
    sun.arch.data.model = 64
    sun.java.command = TaxiLocationServer2.jar
    java.home = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre
    user.language = en
    java.specification.vendor = Oracle Corporation
    awt.toolkit = sun.awt.X11.XToolkit
    java.vm.info = mixed mode
    java.version = 1.8.0_212
    java.ext.dirs = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/ext:/usr/java/packages/lib/ext
    sun.boot.class.path = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/resources.jar:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/rt.jar:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/jsse.jar:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/jce.jar:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/charsets.jar:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/lib/jfr.jar:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el6_10.x86_64/jre/classes
    java.vendor = Oracle Corporation
    file.separator = /
    java.vendor.url.bug = http://bugreport.sun.com/bugreport/
    sun.io.unicode.encoding = UnicodeLittle
    sun.cpu.endian = little
    sun.cpu.isalist = 
    
    VM Flags:
    Non-default VM flags: -XX:CICompilerCount=2 -XX:InitialHeapSize=264241152 -XX:MaxHeapSize=4217372672 -XX:MaxNewSize=1405616128 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=88080384 -XX:OldSize=176160768 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
    Command line:  

    下面的命令显示了新生代对象晋升到老年代对象的最大年龄。在运行程序运行时并没有指定这个参数,但是通过jinfo,可以查看这个参数的当前的值。

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jinfo -flag MaxTenuringThreshold 25699
    -XX:MaxTenuringThreshold=15

    下面的命令显示是否打印gc详细信息:

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jinfo -flag PrintGCDetails  25699
    -XX:-PrintGCDetails

    下面的命令在运用程序运行时动态打开打印详细gc信息开关:

    root@iZ2ze1224b1em0jij7qlssZ opt]# jinfo -flag +PrintGCDetails  25699
    [root@iZ2ze1224b1em0jij7qlssZ opt]# jinfo -flag PrintGCDetails  25699
    -XX:+PrintGCDetails

    注意事项:jinfo虽然可以在java程序运行时动态地修改虚拟机参数,但并不是所有的参数都支持动态修改。

    7、jcmd

    在JDK 1.7之后,新增了一个命令行工具jcmd。它是一个多功能工具,可以用来导出堆,查看java进程,导出线程信息,执行GC等。jcmd拥有jmap的大部分功能,Oracle官方建议使用jcmd代替jmap。

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jcmd -l
    26949 org.apache.zookeeper.server.quorum.QuorumPeerMain /var/zookeeper-3.3.6/bin/../conf/zoo.cfg
    10220 inner-0.0.1-SNAPSHOT.jar

    针对每一个虚拟机,可以使用help命令列出该虚拟机支持的所有命令:

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jcmd  25699 help
    25699:
    The following commands are available:
    VM.native_memory
    ManagementAgent.stop
    ManagementAgent.start_local
    ManagementAgent.start
    VM.classloader_stats
    GC.rotate_log
    Thread.print
    GC.class_stats
    GC.class_histogram
    GC.heap_dump
    GC.finalizer_info
    GC.heap_info
    GC.run_finalization
    GC.run
    VM.uptime
    VM.dynlibs
    VM.flags
    VM.system_properties
    VM.command_line
    VM.version
    help
    
    For more information about a specific command use 'help <command>'.

    子命令含义:
      VM.native_memory
      VM.commercial_features
      GC.rotate_log
      ManagementAgent.stop
      ManagementAgent.start_local
      ManagementAgent.start
      Thread.print, 打印线程栈信息
      GC.class_histogram, 查看系统中类统计信息
      GC.heap_dump, 导出堆信息,与jmap -dump功能一样
      GC.run_finalization, 触发finalize()
      GC.run, 触发gc()
      VM.uptime, VM启动时间
      VM.flags, 获取JVM启动参数
      VM.system_properties, 获取系统Properties
      VM.command_line, 启动时命令行指定的参数
      VM.version
      help

    示例:

    [root@iZ2ze1224b1em0jij7qlssZ opt]# jcmd  25699 VM.uptime
    25699:
    10286927.045 s
    [root@iZ2ze1224b1em0jij7qlssZ opt]# jcmd  25699 VM.flags
    25699:
    -XX:CICompilerCount=2 -XX:InitialHeapSize=264241152 -XX:MaxHeapSize=4217372672 -XX:MaxNewSize=1405616128 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=88080384 -XX:OldSize=176160768 -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
    [root@iZ2ze1224b1em0jij7qlssZ opt]# jcmd  25699 VM.command_line
    25699:
    VM Arguments:
    java_command: TaxiLocationServer2.jar
    java_class_path (initial): TaxiLocationServer2.jar
    Launcher Type: SUN_STANDARD

    8、可视化监控工具(JConsole、JVisualVM)

    集上面之大成,并提供了可视化的界面;还可以监控远程Java服务;支持监控JMX。

    JVisualVM比JConsole更强大:支持对CPU、内存运行进行采样、配置。推荐用JVisualVM。

    JConsole监控页面示例:

    JVisualVM监控页面示例:

    参考:

    https://www.cnblogs.com/z-sm/p/6745375.html

    https://blog.csdn.net/wangzhongshun/article/details/112545871

    https://blog.csdn.net/yx0628/article/details/80958488

  • 相关阅读:
    Visual Studio 2008 菜单:工具+选项+文本编辑器+HTML+格式,选中“键入时插入属性值引号”
    itemarray的意思
    SQL技巧大全
    IIS调用com组件的权限问题
    网站快速备案法(1小时)
    ASP.NET 2.0中WEB应用程序的部署
    c#中MessageBox的使用
    推荐一款DataGridView的打印解决方案
    使用C#格式化字符串
    关于MSSQL导入导出时主键与约束丢失的问题解决
  • 原文地址:https://www.cnblogs.com/sfnz/p/15010163.html
Copyright © 2011-2022 走看看