在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