引用jijs作者:https://www.jianshu.com/p/c11010ccedce
引用楼兰King作者:https://www.jianshu.com/p/213710fb9e40
有时候我们会碰到下面这些问题:
-
OutOfMemoryError,内存不足
-
内存泄露
-
线程死锁
-
锁争用(Lock Contention)
-
Java进程消耗CPU过高
-
......
这些问题在日常开发、维护中可能被很多人忽视(比如有的人遇到上面的问题只是重启服务器或者调大内存,而不会深究问题根源),但能够理解并解决这些问题是Java程序员进阶的必备要求。本文将对一些常用的JVM性能调优监控工具进行介绍,希望能起抛砖引玉之用。
而且这些监控、调优工具的使用,无论你是运维、开发、测试,都是必须掌握的。
A、 jps(Java Virtual Machine Process Status Tool)
jps主要用来输出JVM中运行的进程状态信息。语法格式如下:
jps [options] [hostid]
如果不指定hostid就默认为当前主机或服务器。
命令行参数选项说明如下:
-q 不输出类名、Jar名和传入main方法的参数-m 输出传入main方法的参数-l 输出main类或Jar的全限名-v 输出传入JVM的参数
比如下面:
root@ubuntu:/# jps -m -l2458 org.artifactory.standalone.main.Main /usr/local/artifactory-2.2.5/etc/jetty.xml29920 com.sun.tools.hat.Main -port 9998 /tmp/dump.dat3149 org.apache.catalina.startup.Bootstrap start30972 sun.tools.jps.Jps -m -l8247 org.apache.catalina.startup.Bootstrap start25687 com.sun.tools.hat.Main -port 9999 dump.dat21711 mrf-center.jar
B、 jstack
jstack主要用来查看某个Java进程内的线程堆栈信息。语法格式如下:
jstack [option] pidjstack [option] executable corejstack [option] [server-id@]remote-hostname-or-ip
命令行参数选项说明如下:
-l long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况-m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)
jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep。
第一步先找出Java进程ID,我部署在服务器上的Java应用名称为mrf-center:
[root@ovy-log-kafka-01 ~]# ps -ef | grep kafka | grep -v grep
root 3645 1 16 2019 ? 108-21:21:41 /opt/jdk1.8.0_144/bin/java -Xmx4G -Xms4G -server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -Djava.awt.headless=true -Xloggc:/data/software/kafka_2.11-1.1.0/bin/../logs/kafkaServer-gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dkafka.logs.dir=/data/software/kafka_2.11-1.1.0/bin/../logs -Dlog4j.configuration=file:./bin/../config/log4j.properties -cp .:/opt/jdk1.8.0_144/lib/dt.jar:/opt/jdk1.8.0_144/lib/tools.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/aopalliance-repackaged-2.5.0-b32.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/argparse4j-0.7.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/commons-lang3-3.5.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/connect-api-1.1.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/connect-file-1.1.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/connect-json-1.1.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/connect-runtime-1.1.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/connect-transforms-1.1.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/guava-20.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/hk2-api-2.5.0-b32.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/hk2-locator-2.5.0-b32.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/hk2-utils-2.5.0-b32.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jackson-annotations-2.9.4.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jackson-core-2.9.4.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jackson-databind-2.9.4.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jackson-jaxrs-base-2.9.4.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jackson-jaxrs-json-provider-2.9.4.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jackson-module-jaxb-annotations-2.9.4.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/javassist-3.20.0-GA.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/javassist-3.21.0-GA.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/javax.annotation-api-1.2.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/javax.inject-1.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/javax.inject-2.5.0-b32.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/javax.servlet-api-3.1.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/javax.ws.rs-api-2.0.1.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jersey-client-2.25.1.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jersey-common-2.25.1.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jersey-container-servlet-2.25.1.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jersey-container-servlet-core-2.25.1.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jersey-guava-2.25.1.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jersey-media-jaxb-2.25.1.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jersey-server-2.25.1.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jetty-client-9.2.24.v20180105.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jetty-continuation-9.2.24.v20180105.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jetty-http-9.2.24.v20180105.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jetty-io-9.2.24.v20180105.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jetty-security-9.2.24.v20180105.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jetty-server-9.2.24.v20180105.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jetty-servlet-9.2.24.v20180105.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jetty-servlets-9.2.24.v20180105.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jetty-util-9.2.24.v20180105.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/jopt-simple-5.0.4.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/kafka_2.11-1.1.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/kafka_2.11-1.1.0-sources.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/kafka_2.11-1.1.0-test-sources.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/kafka-clients-1.1.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/kafka-log4j-appender-1.1.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/kafka-streams-1.1.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/kafka-streams-examples-1.1.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/kafka-streams-test-utils-1.1.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/kafka-tools-1.1.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/log4j-1.2.17.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/lz4-java-1.4.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/maven-artifact-3.5.2.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/metrics-core-2.2.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/osgi-resource-locator-1.0.1.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/plexus-utils-3.1.0.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/reflections-0.9.11.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/rocksdbjni-5.7.3.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/scala-library-2.11.12.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/scala-logging_2.11-3.7.2.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/scala-reflect-2.11.12.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/slf4j-api-1.7.25.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/slf4j-log4j12-1.7.25.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/snappy-java-1.1.7.1.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/validation-api-1.1.0.Final.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/zkclient-0.10.jar:/data/software/kafka_2.11-1.1.0/bin/../libs/zookeeper-3.4.10.jar kafka.Kafka config/server.properties
得到进程ID为21711,第二步找出该进程内最耗费CPU的线程,
可以使用如下三个命令任意一个:
ps -Lfp pid
ps -mp pid -o THREAD, tid, time
top -Hp pid
,我这里用第三个,输出如下:
[root@ovy-log-kafka-01 ~]# top -Hp 3645
top - 14:56:12 up 659 days, 17:43, 1 user, load average: 0.09, 0.09, 0.13
Threads: 84 total, 0 running, 84 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.7 us, 0.3 sy, 0.0 ni, 98.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 16267740 total, 153728 free, 5108744 used, 11005268 buff/cache
KiB Swap: 8388604 total, 8155132 free, 233472 used. 9952292 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3920 root 20 0 23.512g 4.416g 21536 S 2.3 28.5 22552:09 java
3922 root 20 0 23.512g 4.416g 21536 S 2.3 28.5 22566:36 java
3923 root 20 0 23.512g 4.416g 21536 S 2.3 28.5 22524:56 java
3919 root 20 0 23.512g 4.416g 21536 S 2.0 28.5 22561:47 java
3921 root 20 0 23.512g 4.416g 21536 S 2.0 28.5 22856:09 java
3906 root 20 0 23.512g 4.416g 21536 S 0.7 28.5 4345:16 java
3678 root 20 0 23.512g 4.416g 21536 S 0.3 28.5 396:56.70 java
3681 root 20 0 23.512g 4.416g 21536 S 0.3 28.5 3055:26 java
3903 root 20 0 23.512g 4.416g 21536 S 0.3 28.5 1934:42 java
3905 root 20 0 23.512g 4.416g 21536 S 0.3 28.5 2409:07 java
3907 root 20 0 23.512g 4.416g 21536 S 0.3 28.5 2069:17 java
3645 root 20 0 23.512g 4.416g 21536 S 0.0 28.5 0:00.00 java
3646 root 20 0 23.512g 4.416g 21536 S 0.0 28.5 0:01.88 java
3647 root 20 0 23.512g 4.416g 21536 S 0.0 28.5 417:50.38 java
3648 root 20 0 23.512g 4.416g 21536 S 0.0 28.5 417:56.07 java
3649 root 20 0 23.512g 4.416g 21536 S 0.0 28.5 417:50.12 java
3650 root 20 0 23.512g 4.416g 21536 S 0.0 28.5 418:09.05 java
TIME列就是各个Java线程耗费的CPU时间,CPU时间最长的是线程ID为21742的线程,用
[root@ovy-log-kafka-01 ~]# printf "%x\n" 3920
f50
得到3920的十六进制值为f50,下面会用到。
OK,下一步终于轮到jstack上场了,它用来输出进程3645的堆栈信息,然后根据线程ID的十六进制值grep,如下:
[root@ovy-log-kafka-01 ~]# jstack 3645 | grep f50
"zk-session-expiry-handler5-SendThread(10.6.1.8:2181)" #94 daemon prio=5 os_prio=0 tid=0x00007fcf5400a800 nid=0x3d50 runnable [0x00007fce188f5000]
"kafka-request-handler-1" #57 daemon prio=5 os_prio=0 tid=0x00007fd00d73e000 nid=0xf50 waiting on condition [0x00007fce18ffa000]
"ExpirationReaper-1-Produce" #44 prio=5 os_prio=0 tid=0x00007fd00d64f000 nid=0xf44 waiting on condition [0x00007fce45af5000]
C、 jmap(Memory Map)和jhat(Java Heap Analysis Tool)
jmap用来查看堆内存使用状况,一般结合jhat使用。
jmap语法格式如下:
jmap [option] pidjmap [option] executable corejmap [option] [server-id@]remote-hostname-or-ip
如果运行在64位JVM上,可能需要指定-J-d64命令选项参数。
我服务器上没有这个jmap 命令没有这个参数-permstat
[root@ovy-log-kafka-01 ~]# java -version
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
jmap -permstat pid
打印进程的类加载器和类加载器加载的持久代对象信息,输出:类加载器名称、对象是否存活(不可靠)、对象地址、父类加载器、已加载的类大小等信息,如下图:
使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。比如下面的例子:
[root@ovy-log-kafka-01 ~]# jmap -heap 3645
Attaching to process ID 3645, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.144-b01
using thread-local object allocation.
Garbage-First (G1) GC with 8 thread(s)
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 4294967296 (4096.0MB)
NewSize = 1363144 (1.2999954223632812MB)
MaxNewSize = 2575302656 (2456.0MB)
OldSize = 5452592 (5.1999969482421875MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 2097152 (2.0MB)
Heap Usage:
G1 Heap:
regions = 2048
capacity = 4294967296 (4096.0MB)
used = 1299213824 (1239.02685546875MB)
free = 2995753472 (2856.97314453125MB)
30.24967908859253% used
G1 Young Generation:
Eden Space:
regions = 118
capacity = 2686451712 (2562.0MB)
used = 247463936 (236.0MB)
free = 2438987776 (2326.0MB)
9.211553473848555% used
Survivor Space:
regions = 9
capacity = 18874368 (18.0MB)
used = 18874368 (18.0MB)
free = 0 (0.0MB)
100.0% used
G1 Old Generation:
regions = 495
capacity = 1589641216 (1516.0MB)
used = 1032875520 (985.02685546875MB)
free = 556765696 (530.97314453125MB)
64.9753862446405% used
21874 interned Strings occupying 3883760 bytes.
使用jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象,如下:
[root@ovy-log-kafka-01 ~]# jmap -histo:live 3645| more num
num #instances #bytes class name
----------------------------------------------
1: 3256 136723744 [B
2: 106172 13906768 [C
3: 106100 2546400 java.lang.String
4: 94329 2263896 java.util.concurrent.ConcurrentSkipListMap$Node
5: 93245 2237880 java.lang.Double
6: 69720 2231040 java.util.HashMap$Node
7: 39199 1254368 java.util.concurrent.ConcurrentHashMap$Node
8: 46546 1117104 java.util.concurrent.ConcurrentSkipListMap$Index
9: 45181 1084344 javax.management.ObjectName$Property
10: 19212 922176 com.yammer.metrics.stats.EWMA
11: 26051 832704 [Ljavax.management.ObjectName$Property;
12: 23592 754944 java.util.Hashtable$Entry
13: 29258 702192 java.util.concurrent.atomic.AtomicLong
14: 21860 699520 org.apache.kafka.common.requests.FetchRequest$PartitionData
15: 6202 689624 java.lang.Class
16: 25879 621096 org.apache.kafka.common.TopicPartition
17: 3226 538232 [Ljava.util.HashMap$Node;
....
class name是对象类型,说明如下:
B byteC charD doubleF floatI intJ longZ boolean[ 数组,如[I表示int[][L+类名 其他对象
还有一个很常用的情况是:用jmap把进程内存使用情况dump到文件中,再用jhat分析查看。jmap进行dump命令格式如下:
jmap -dump:format=b,file=dumpFileName pid
我一样地对上面进程ID为3645进行Dump:
[root@ovy-log-kafka-01 ~]# jmap -dump:format=b,file=dumpFileName 3645
Dumping heap to /root/dumpFileName ...
Heap dump file created
dump出来的文件可以用MAT、VisualVM等工具查看,这里用jhat查看:
jhat -port 9998 /root/dumpFileName
注意如果Dump文件太大,可能需要加上-J-Xmx512m这种参数指定最大堆内存,即jhat -J-Xmx512m -port 9998 /root/dumpFileName 。然后就可以在浏览器中输入主机地址:9998查看了
D、jstat(JVM统计监测工具)
语法格式如下:
jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
vmid是Java虚拟机ID,在Linux/Unix系统上一般就是进程ID。interval是采样时间间隔。count是采样数目。比如下面输出的是GC信息,采样时间间隔为250ms,采样数为4:
[root@ovy-log-kafka-01 ~]# jstat -gc 3645
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
0.0 16384.0 0.0 16384.0 2469888.0 1683456.0 1708032.0 186356.6 36352.0 35845.2 4864.0 4645.6 1920740 33546.457 2 1.286 33547.743
要明白上面各列的意义,先看JVM堆内存布局:
可以看出:
堆内存 = 年轻代 + 年老代 + 永久代年轻代 = Eden区 + 两个Survivor区(From和To)
现在来解释各列含义:
S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used)EC、EU:Eden区容量和使用量OC、OU:年老代容量和使用量PC、PU:永久代容量和使用量YGC、YGT:年轻代GC次数和GC耗时FGC、FGCT:Full GC次数和Full GC耗时GCT:GC总耗时
E、hprof(Heap/CPU Profiling Tool)
hprof能够展现CPU使用率,统计堆内存使用情况。
语法格式如下:
java -agentlib:hprof[=options] ToBeProfiledClassjava -Xrunprof[:options] ToBeProfiledClassjavac -J-agentlib:hprof[=options] ToBeProfiledClass
完整的命令选项如下:
Option Name and Value Description Default--------------------- ----------- -------heap=dump|sites|all heap profiling allcpu=samples|times|old CPU usage offmonitor=y|n monitor contention nformat=a|b text(txt) or binary output afile=<file> write data to file java.hprof[.txt]net=<host>:<port> send data over a socket offdepth=<size> stack trace depth 4interval=<ms> sample interval in ms 10cutoff=<value> output cutoff point 0.0001lineno=y|n line number in traces? ythread=y|n thread in traces? ndoe=y|n dump on exit? ymsa=y|n Solaris micro state accounting nforce=y|n force output to <file> yverbose=y|n print messages about dumps y
来几个官方指南上的实例。
CPU Usage Sampling Profiling(cpu=samples)的例子:
java -agentlib:hprof=cpu=samples,interval=20,depth=3 Hello
上面每隔20毫秒采样CPU消耗信息,堆栈深度为3,生成的profile文件名称是java.hprof.txt,在当前目录。
CPU Usage Times Profiling(cpu=times)的例子,它相对于CPU Usage Sampling Profile能够获得更加细粒度的CPU消耗信息,能够细到每个方法调用的开始和结束,它的实现使用了字节码注入技术(BCI):
javac -J-agentlib:hprof=cpu=times Hello.java
Heap Allocation Profiling(heap=sites)的例子:
javac -J-agentlib:hprof=heap=sites Hello.java
Heap Dump(heap=dump)的例子,它比上面的Heap Allocation Profiling能生成更详细的Heap Dump信息:
javac -J-agentlib:hprof=heap=dump Hello.java
虽然在JVM启动参数中加入-Xrunprof:heap=sites参数可以生成CPU/Heap Profile文件,但对JVM性能影响非常大,不建议在线上服务器环境使用。
作者:楼兰King
链接:https://www.jianshu.com/p/c11010ccedce
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
=================================================
概述
Jstat是JDK自带的一个轻量级小工具。全称“Java Virtual Machine statistics monitoring tool”,它位于java的bin目录下,主要利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控。
jstat 用法
[root@ory-backup-archive-01 /opt]# jstat -h
-h requires an integer argument
Usage: jstat -help|-options
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
Definitions:
<option> An option reported by the -options option
<vmid> Virtual Machine Identifier. A vmid takes the following form:
<lvmid>[@<hostname>[:<port>]]
Where <lvmid> is the local vm identifier for the target
Java virtual machine, typically a process id; <hostname> is
the name of the host running the target Java virtual machine;
and <port> is the port number for the rmiregistry on the
target host. See the jvmstat documentation for a more complete
description of the Virtual Machine Identifier.
<lines> Number of samples between header lines.
<interval> Sampling interval. The following forms are allowed:
<n>["ms"|"s"]
Where <n> is an integer and the suffix specifies the units as
milliseconds("ms") or seconds("s"). The default units are "ms".
<count> Number of samples to take before terminating.
-J<flag> Pass <flag> directly to the runtime system.
- option: 参数选项
- -t: 可以在打印的列加上Timestamp列,用于显示系统运行的时间
- -h: 可以在周期性数据数据的时候,可以在指定输出多少行以后输出一次表头
- vmid: Virtual Machine ID( 进程的 pid)
- interval: 执行每次的间隔时间,单位为毫秒
- count: 用于指定输出多少次记录,缺省则会一直打印
[root@ory-backup-archive-01 /opt]# jstat -options
-class
-compiler
-gc
-gccapacity
-gccause
-gcmetacapacity
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcutil
-printcompilation
option 可以从下面参数中选择
- -class 显示ClassLoad的相关信息;
- -compiler 显示JIT编译的相关信息;
- -gc 显示和gc相关的堆信息;
- -gccapacity 显示各个代的容量以及使用情况;
- -gcmetacapacity 显示metaspace的大小
- -gcnew 显示新生代信息;
- -gcnewcapacity 显示新生代大小和使用情况;
- -gcold 显示老年代和永久代的信息;
- -gcoldcapacity 显示老年代的大小;
- -gcutil 显示垃圾收集信息;
- -gccause 显示垃圾回收的相关信息(通-gcutil),同时显示最后一次或当前正在发生的垃圾回收的诱因;
- -printcompilation 输出JIT编译的方法信息;
示例一:-class
显示加载class的数量,及所占空间等信息。
[root@ovy-log-kafka-01 ~]# jstat -class 3645
Loaded Bytes Unloaded Bytes Time
5831 11593.5 15 15.6 40.46
- Loaded : 已经装载的类的数量
- Bytes : 装载类所占用的字节数
- Unloaded:已经卸载类的数量
- Bytes:卸载类的字节数
- Time:装载和卸载类所花费的时间
示例二: -compiler
显示VM实时编译(JIT)的数量等信息。
[root@ovy-log-kafka-01 ~]# jstat -compiler 3645
Compiled Failed Invalid Time FailedType FailedMethod
14729 2 0 115.16 1 kafka/server/KafkaRequestHandler run
- Compiled:编译任务执行数量
- Failed:编译任务执行失败数量
- Invalid :编译任务执行失效数量
- Time :编译任务消耗时间
- FailedType:最后一个编译失败任务的类型
- FailedMethod:最后一个编译失败任务所在的类及方法
示例三: -gc
显示gc相关的堆信息,查看gc的次数,及时间。
[root@ovy-log-kafka-01 ~]# jstat -gc 3645
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
0.0 40960.0 0.0 40960.0 354304.0 155648.0 3799040.0 963172.5 36224.0 35799.8 4736.0 4628.7 1920658 33545.019 0 0.000 33545.019
- S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
- S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
- S0U :年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
- S1U :年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
- EC :年轻代中Eden(伊甸园)的容量 (字节)
- EU :年轻代中Eden(伊甸园)目前已使用空间 (字节)
- OC :Old代的容量 (字节)
- OU :Old代目前已使用空间 (字节)
- MC:metaspace(元空间)的容量 (字节)
- MU:metaspace(元空间)目前已使用空间 (字节)
- YGC :从应用程序启动到采样时年轻代中gc次数
- YGCT :从应用程序启动到采样时年轻代中gc所用时间(s)
- FGC :从应用程序启动到采样时old代(全gc)gc次数
- FGCT :从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT:从应用程序启动到采样时gc用的总时间(s)
示例四: -gccapacity
可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小
[root@ovy-log-kafka-01 ~]# jstat -gccapacity 3645
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC
0.0 4194304.0 1503232.0 0.0 16384.0 1486848.0 0.0 4194304.0 2691072.0 2691072.0 0.0 1081344.0 36224.0 0.0 1048576.0 4736.0 1920659 0
- NGCMN :年轻代(young)中初始化(最小)的大小(字节)
- NGCMX :年轻代(young)的最大容量 (字节)
- NGC :年轻代(young)中当前的容量 (字节)
- S0C :年轻代中第一个survivor(幸存区)的容量 (字节)
- S1C : 年轻代中第二个survivor(幸存区)的容量 (字节)
- EC :年轻代中Eden(伊甸园)的容量 (字节)
- OGCMN :old代中初始化(最小)的大小 (字节)
- OGCMX :old代的最大容量(字节)
- OGC:old代当前新生成的容量 (字节)
- OC :Old代的容量 (字节)
- MCMN:metaspace(元空间)中初始化(最小)的大小 (字节)
- MCMX :metaspace(元空间)的最大容量 (字节)
- MC :metaspace(元空间)当前新生成的容量 (字节)
- CCSMN:最小压缩类空间大小
- CCSMX:最大压缩类空间大小
- CCSC:当前压缩类空间大小
- YGC :从应用程序启动到采样时年轻代中gc次数
- FGC:从应用程序启动到采样时old代(全gc)gc次数
示例五:-gcmetacapacity
metaspace 中对象的信息及其占用量。
[root@ovy-log-kafka-01 ~]# jstat -gcmetacapacity 3645
MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT
0.0 1081344.0 36224.0 0.0 1048576.0 4736.0 1920662 0 0.000 33545.084
- MCMN:最小元数据容量
- MCMX:最大元数据容量
- MC:当前元数据空间大小
- CCSMN:最小压缩类空间大小
- CCSMX:最大压缩类空间大小
- CCSC:当前压缩类空间大小
- YGC :从应用程序启动到采样时年轻代中gc次数
- FGC :从应用程序启动到采样时old代(全gc)gc次数
- FGCT :从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT:从应用程序启动到采样时gc用的总时间(s)
示例六: -gcnew
年轻代对象的信息。
[root@ovy-log-kafka-01 ~]# jstat -gcnew 3645
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
0.0 14336.0 0.0 14336.0 15 15 108544.0 2416640.0 397312.0 1920663 33545.099
- S0C :年轻代中第一个survivor(幸存区)的容量 (字节)
- S1C :年轻代中第二个survivor(幸存区)的容量 (字节)
- S0U :年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
- S1U :年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
- TT:持有次数限制
- MTT:最大持有次数限制
- DSS:期望的幸存区大小
- EC:年轻代中Eden(伊甸园)的容量 (字节)
- EU :年轻代中Eden(伊甸园)目前已使用空间 (字节)
- YGC :从应用程序启动到采样时年轻代中gc次数
- YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)
示例七: -gcnewcapacity
年轻代对象的信息及其占用量
[root@ovy-log-kafka-01 ~]# jstat -gcnewcapacity 3645
NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC
0.0 4194304.0 2031616.0 0.0 0.0 4194304.0 26624.0 4194304.0 2004992.0 1920664 0
- NGCMN :年轻代(young)中初始化(最小)的大小(字节)
- NGCMX :年轻代(young)的最大容量 (字节)
- NGC :年轻代(young)中当前的容量 (字节)
- S0CMX :年轻代中第一个survivor(幸存区)的最大容量 (字节)
- S0C :年轻代中第一个survivor(幸存区)的容量 (字节)
- S1CMX :年轻代中第二个survivor(幸存区)的最大容量 (字节)
- S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
- ECMX:年轻代中Eden(伊甸园)的最大容量 (字节)
- EC:年轻代中Eden(伊甸园)的容量 (字节)
- YGC:从应用程序启动到采样时年轻代中gc次数
- FGC:从应用程序启动到采样时old代(全gc)gc次数
示例八: -gcold
old代对象的信息
[root@ovy-log-kafka-01 ~]# jstat -gcold 3645
MC MU CCSC CCSU OC OU YGC FGC FGCT GCT
36224.0 35799.8 4736.0 4628.7 2217984.0 979937.0 1920665 0 0.000 33545.137
- MC :metaspace(元空间)的容量 (字节)
- MU:metaspace(元空间)目前已使用空间 (字节)
- CCSC:压缩类空间大小
- CCSU:压缩类空间使用大小
- OC:Old代的容量 (字节)
- OU:Old代目前已使用空间 (字节)
- YGC:从应用程序启动到采样时年轻代中gc次数
- FGC:从应用程序启动到采样时old代(全gc)gc次数
- FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT:从应用程序启动到采样时gc用的总时间(s)
示例九:-gcoldcapacity
old代对象的信息及其占用量
[root@ovy-log-kafka-01 ~]# jstat -gcoldcapacity 3645
OGCMN OGCMX OGC OC YGC FGC FGCT GCT
0.0 4194304.0 2217984.0 2217984.0 1920665 0 0.000 33545.137
- OGCMN :old代中初始化(最小)的大小 (字节)
- OGCMX :old代的最大容量(字节)
- OGC :old代当前新生成的容量 (字节)
- OC :Old代的容量 (字节)
- YGC :从应用程序启动到采样时年轻代中gc次数
- FGC :从应用程序启动到采样时old代(全gc)gc次数
- FGCT :从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT:从应用程序启动到采样时gc用的总时间(s)
示例十: - gcutil
统计gc信息
[root@ovy-log-kafka-01 ~]# jstat -gcutil 3645
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 100.00 58.45 51.57 98.83 97.73 1920666 33545.152 0 0.000 33545.152
- S0 :年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
- S1 :年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
- E :年轻代中Eden(伊甸园)已使用的占当前容量百分比
- O :old代已使用的占当前容量百分比
- P :perm代已使用的占当前容量百分比
- YGC :从应用程序启动到采样时年轻代中gc次数
- YGCT :从应用程序启动到采样时年轻代中gc所用时间(s)
- FGC :从应用程序启动到采样时old代(全gc)gc次数
- FGCT :从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT:从应用程序启动到采样时gc用的总时间(s)
示例十一:-gccause
显示垃圾回收的相关信息(通-gcutil),同时显示最后一次或当前正在发生的垃圾回收的诱因。
[root@ovy-log-kafka-01 ~]# jstat -gccause 3645
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC
0.00 100.00 23.19 48.44 98.83 97.73 1920667 33545.172 0 0.000 33545.172 G1 Evacuation Pause No GC
- LGCC:最后一次GC原因
- GCC:当前GC原因(No GC 为当前没有执行GC)
示例十二: -printcompilation
当前VM执行的信息。
[root@ovy-log-kafka-01 ~]# jstat -printcompilation 3645
Compiled Size Type Method
14729 12 1 scala/collection/AbstractMap keys
- Compiled :编译任务的数目
- Size :方法生成的字节码的大小
- Type:编译类型
- Method:类名和方法名用来标识编译的方法。类名使用/做为一个命名空间分隔符。方法名是给定类中的方法。上述格式是由-XX:+PrintComplation选项进行设置的