JVM线上监控工具
JVM线上监控工具
如果想要查看java进程中线程堆栈的信息,可以选择jstack命令
如果要查看对内存,可以使用jmap导出并使用jhat来进行分析,包括查看类的加载信息,GC算法,对象的使用情况等.
可以使用jstat来对JVM进行统计监测,包括查看各个区内存和GC的情况,还可以使用hprof查看CPU使用率,统计堆内存使用情况,
1.jps进程监控工具
jps是用于查看有权访问的hotspot虚拟机的进程,当未指定hostid时,默认查看本机jvm进程,否则查看指定hostid机器上的jvm进程,此时hostid所指机器必须开启jstatd服务
jps可以列出jvm进程lvmid,主类类名,main函数参数,jvm参数,jar名称等信息.
命令格式如下:
```plain text usage: jps [-help] [-mlvV] [
Definitions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
参数含义如下:
- q: 不输出 类名称、Jar 名称 和传入 main 方法的 参数;
- l: 输出 main 类或 Jar 的 全限定名称;
- m: 输出传入 main 方法的 参数;
- v: 输出传入 JVM 的参数。
2.jinfo配置信息查看工具
jinfo(JVM Configuration info) 这个命令作用是实时查看和调整虚拟机运行参数,之前的jps -v命令只能查看到显示指定的参数,如果想要查看未显示的参数的值就要使用jinfo命令
```plain text
Usage:
jinfo [option] <pid>
(to connect to running process)
jinfo [option] <executable <core>
(to connect to a core file)
jinfo [option] [server_id@]<remote server IP or hostname>
(to connect to remote debug server)
参数含义如下:
- pid:本地 jvm 服务的进程 ID;
- executable core:打印 堆栈跟踪 的核心文件;
- remote server IP/hostname:远程 debug 服务的 主机名 或 IP 地址;
- server id:远程 debug 服务的 进程 ID。
参数选项说明如下:
| 参数 | 参数含义 |
|---|---|
| flag | 输出指定 args 参数的值 |
| flags | 不需要 args 参数,输出所有 JVM 参数的值 |
| sysprops | 输出系统属性,等同于 System.getProperties() |
查看正在运行的 jvm 进程的 扩展参数。
```plain text $ jinfo -flags 31983 Attaching to process ID 31983, please wait… Debugger attached successfully. Server compiler detected. JVM version is 25.91-b14 Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=20971520 -XX:MaxHeapFreeRatio=90 -XX:MaxHeapSize=20971520 -XX:MaxNewSize=2097152 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=2097152 -XX:OldSize=18874368 -XX:+PrintGC -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC Command line: -Xmx20m -Xms20m -Xmn2m -javaagent:/opt/idea-IU-181.4668.68/lib/idea_rt.jar=34989:/opt/idea-IU-181.4668.68/bin -Dfile.encoding=UTF-8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
查看正在运行的 jvm 进程的所有 参数信息。
```plain text
$ jinfo 31983
Attaching to process ID 31983, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.91-b14
Java System Properties:
java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.91-b14
sun.boot.library.path = /opt/jdk1.8.0_91/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 = Java HotSpot(TM) 64-Bit Server VM
sun.os.patch.level = unknown
sun.java.launcher = SUN_STANDARD
user.country = CN
user.dir = /home/linchen/projects
java.vm.specification.name = Java Virtual Machine Specification
java.runtime.version = 1.8.0_91-b14
java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
os.arch = amd64
java.endorsed.dirs = /opt/jdk1.8.0_91/jre/lib/endorsed
java.io.tmpdir = /tmp
line.separator =
java.vm.specification.vendor = Oracle Corporation
os.name = Linux
sun.jnu.encoding = UTF-8
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 = 4.15.0-24-generic
user.home = /home/linchen
user.timezone =
java.awt.printerjob = sun.print.PSPrinterJob
file.encoding = UTF-8
java.specification.version = 1.8
user.name = linchen
java.class.path = /opt/jdk1.8.0_91/jre/lib/charsets.jar:/opt/jdk1.8.0_91/jre/lib/deploy.jar:/opt/jdk1.8.0_91/jre/lib/ext/cldrdata.jar:/opt/jdk1.8.0_91/jre/lib/ext/dnsns.jar:/opt/jdk1.8.0_91/jre/lib/ext/jaccess.jar:/opt/jdk1.8.0_91/jre/lib/ext/jfxrt.jar:/opt/jdk1.8.0_91/jre/lib/ext/localedata.jar:/opt/jdk1.8.0_91/jre/lib/ext/nashorn.jar:/opt/jdk1.8.0_91/jre/lib/ext/sunec.jar:/opt/jdk1.8.0_91/jre/lib/ext/sunjce_provider.jar:/opt/jdk1.8.0_91/jre/lib/ext/sunpkcs11.jar:/opt/jdk1.8.0_91/jre/lib/ext/zipfs.jar:/opt/jdk1.8.0_91/jre/lib/javaws.jar:/opt/jdk1.8.0_91/jre/lib/jce.jar:/opt/jdk1.8.0_91/jre/lib/jfr.jar:/opt/jdk1.8.0_91/jre/lib/jfxswt.jar:/opt/jdk1.8.0_91/jre/lib/jsse.jar:/opt/jdk1.8.0_91/jre/lib/management-agent.jar:/opt/jdk1.8.0_91/jre/lib/plugin.jar:/opt/jdk1.8.0_91/jre/lib/resources.jar:/opt/jdk1.8.0_91/jre/lib/rt.jar:/home/linchen/IdeaProjects/core_java/target/classes:/home/linchen/.m2/repository/io/netty/netty-all/4.1.7.Final/netty-all-4.1.7.Final.jar:/home/linchen/.m2/repository/junit/junit/4.12/junit-4.12.jar:/home/linchen/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/home/linchen/.m2/repository/com/lmax/disruptor/3.3.0/disruptor-3.3.0.jar:/home/linchen/.m2/repository/com/rabbitmq/amqp-client/5.3.0/amqp-client-5.3.0.jar:/home/linchen/.m2/repository/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar:/opt/idea-IU-181.4668.68/lib/idea_rt.jar
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = com.own.learn.jvm.JinfoTest
java.home = /opt/jdk1.8.0_91/jre
user.language = zh
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.X11.XToolkit
java.vm.info = mixed mode
java.version = 1.8.0_91
java.ext.dirs = /opt/jdk1.8.0_91/jre/lib/ext:/usr/java/packages/lib/ext
sun.boot.class.path = /opt/jdk1.8.0_91/jre/lib/resources.jar:/opt/jdk1.8.0_91/jre/lib/rt.jar:/opt/jdk1.8.0_91/jre/lib/sunrsasign.jar:/opt/jdk1.8.0_91/jre/lib/jsse.jar:/opt/jdk1.8.0_91/jre/lib/jce.jar:/opt/jdk1.8.0_91/jre/lib/charsets.jar:/opt/jdk1.8.0_91/jre/lib/jfr.jar:/opt/jdk1.8.0_91/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.desktop = gnome
sun.cpu.isalist =
VM Flags:
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=20971520 -XX:MaxHeapFreeRatio=90 -XX:MaxHeapSize=20971520 -XX:MaxNewSize=2097152 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=2097152 -XX:OldSize=18874368 -XX:+PrintGC -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC
Command line: -Xmx20m -Xms20m -Xmn2m -javaagent:/opt/idea-IU-181.4668.68/lib/idea_rt.jar=34989:/opt/idea-IU-181.4668.68/bin -Dfile.encoding=UTF-8
查看正在运行的 jvm 进程的 环境变量信息。
```plain text $ jinfo -sysprops 31983 Attaching to process ID 31983, please wait… Debugger attached successfully. Server compiler detected. JVM version is 25.91-b14 java.runtime.name = Java(TM) SE Runtime Environment java.vm.version = 25.91-b14 sun.boot.library.path = /opt/jdk1.8.0_91/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 = Java HotSpot(TM) 64-Bit Server VM sun.os.patch.level = unknown sun.java.launcher = SUN_STANDARD user.country = CN user.dir = /home/linchen/projects java.vm.specification.name = Java Virtual Machine Specification java.runtime.version = 1.8.0_91-b14 java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment os.arch = amd64 java.endorsed.dirs = /opt/jdk1.8.0_91/jre/lib/endorsed java.io.tmpdir = /tmp line.separator =
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
### **2. jstat信息统计监控工具**
jstat 是用于识别 **虚拟机** 各种 **运行状态信息** 的命令行工具。它可以显示 **本地** 或者 **远程虚拟机** 进程中的 **类装载**、**内存**、**垃圾收集**、jit **编译** 等运行数据,它是 **线上** 定位 jvm **性能** 的首选工具。
jstat 工具提供如下的 jvm 监控功能:
1. **类的加载卸载**
及
的情况;
2. 查看 **新生代老生代元空间容量**
、
及
(MetaSpace)的
及使用情况;
3. 查看 **新生代老生代元空间垃圾回收情况次数时间**
、
及
(MetaSpace)的
,包括垃圾回收的
,垃圾回收所占用的
;
4. 查看 **新生代容量分配情况**
中 Eden 区及 Survior 区中
及
等。
命令格式如下:
```plain text
Usage: jstat -help|-options
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
参数含义如下:
- option: 参数选项。
- t: 可以在打印的列加上 timestamp 列,用于显示系统运行的时间。
- h: 可以在 周期性数据表头 的时候,可以在指定输出多少行以后输出一次 。
- vmid: Virtual Machine ID(进程的 pid)。
- lines: 表头表头 与 的间隔行数。
- interval: 执行每次的 间隔时间毫秒 ,单位为 。
- count: 用于指定输出记录的 次数 ,缺省则会一直打印。
参数选项说明如下:
- class: 显示 类加载 ClassLoad 的相关信息;
- compiler: 显示 JIT 编译 的相关信息;
- gc: 显示和 gc 相关的 堆信息 ;
- gccapacity: 显示 各个代容量使用情况 的 以及 ;
- gcmetacapacity: 显示 元空间 metaspace 的大小;
- gcnew: 显示 新生代 信息;
- gcnewcapacity: 显示 新生代大小使用情况 和 ;
- gcold: 显示 老年代永久代 和 的信息;
- gcoldcapacity: 显示 老年代 的大小;
- gcutil: 显示 垃圾回收信息 ;
- gccause: 显示 垃圾回收最后一次当前诱因 的相关信息(同 -gcutil),同时显示 或 正在发生的垃圾回收的 ;
- printcompilation: 输出 JIT 编译 的方法信息;
2.1. class
显示和监视 类装载、卸载数量、总空间 以及 耗费的时间。
```plain text $ jstat -class 8615 Loaded Bytes Unloaded Bytes Time 7271 13325.8 1 0.9 2.98
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| 参数 | 参数含义 |
| --- | --- |
| Loaded | 已经装载的类的数量 |
| Bytes | 装载类所占用的字节数 |
| Unloaded | 已经卸载类的数量 |
| Bytes | 卸载类的字节数 |
| Time | 装载和卸载类所花费的时间 |
### **2.2. compiler**
显示虚拟机 **实时编译**(JIT)的 **次数** 和 **耗时** 等信息。
```plain text
$ jstat -compiler 8615
Compiled Failed Invalid Time FailedType FailedMethod
3886 0 0 1.29 0
参数列表及含义如下:
| 参数 | 参数含义 |
|---|---|
| Compiled | 编译任务执行数量 |
| Failed | 编译任务执行失败数量 |
| Invalid | 编译任务执行失效数量 |
| Time | 编译任务消耗时间 |
| FailedType | 最后一个编译失败任务的类型 |
| FailedMethod | 最后一个编译失败任务所在的类及方法 |
2.3. gc
显示 垃圾回收(gc)相关的 堆信息,查看 gc 的 次数 及 时间。
```plain text $ jstat -gc 8615 S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT 20480.0 10752.0 0.0 0.0 262128.0 130750.7 165376.0 24093.7 35456.0 33931.0 4992.0 4582.0 5 0.056 2 0.075 0.131
1
2
3
4
5
6
7
8
9
10
比如下面输出的是 GC 信息,采样 **时间间隔** 为 250ms,采样数为 4:
```plain text
$ jstat -gc 8615 250 4
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
20480.0 10752.0 0.0 0.0 262144.0 130750.7 165376.0 24093.7 35456.0 33931.0 4992.0 4582.0 5 0.056 2 0.075 0.131
20480.0 10752.0 0.0 0.0 262872.0 130750.7 165376.0 24093.7 35456.0 33931.0 4992.0 4582.0 5 0.056 2 0.075 0.131
20480.0 10752.0 0.0 0.0 262720.0 130750.7 165376.0 24093.7 35456.0 33931.0 4992.0 4582.0 5 0.056 2 0.075 0.131
20480.0 10752.0 0.0 0.0 262446.0 130750.7 165376.0 24093.7 35456.0 33931.0 4992.0 4582.0 5 0.056 2 0.075 0.131
参数列表及含义如下:
| 参数 | 参数含义 |
|---|---|
| S0C | 年轻代中第一个 survivor 的容量 |
| S1C | 年轻代中第二个 survivor 的容量 |
| S0U | 年轻代中第一个 survivor 目前已使用空间 |
| S1U | 年轻代中第二个 survivor 目前已使用空间 |
| EC | 年轻代中 Eden 的容量 |
| EU | 年轻代中 Eden 目前已使用空间 |
| OC | 老年代的容量 |
| OU | 老年代目前已使用空间 |
| MC | 元空间 metaspace 的容量 |
| MU | 元空间 metaspace 目前已使用空间 |
| YGC | 从应用程序启动到采样时 年轻代 中 gc 次数 |
| YGCT | 从应用程序启动到采样时 年轻代 中 gc 所用时间 |
| FGC | 从应用程序启动到采样时 老年代 中 gc 次数 |
| FGCT | 从应用程序启动到采样时 老年代 中 gc 所用时间 |
| GCT | 从应用程序启动到采样时 gc 用的 总时间 |
2.4. gccapacity
显示 虚拟机内存 中三代 年轻代(young),老年代(old),元空间(metaspace)对象的使用和占用大小。
```plain text $ jstat -gccapacity 8615 NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC 87040.0 1397760.0 372736.0 20480.0 10752.0 262144.0 175104.0 2796544.0 165376.0 165376.0 0.0 1079296.0 35456.0 0.0 1048576.0 4992.0 5 2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
参数列表及含义如下:
| 参数 | 参数含义 |
| --- | --- |
| NGCMN | 年轻代的 **初始化**(最小)容量 |
| NGCMX | 年轻代的 **最大容量** |
| NGC | 年轻代 **当前的容量** |
| S0C | 年轻代中 **第一个** survivor 区的容量 |
| S1C | 年轻代中 **第二个** survivor 区的容量 |
| EC | 年轻代中 Eden(**伊甸园**)的容量 |
| OGCMN | 老年代中 **初始化**(最小)容量 |
| OGCMX | 老年代的 **最大容量** |
| OGC | 老年代 **当前新生成** 的容量 |
| OC | 老年代的容量大小 |
| MCMN | **元空间** 的 **初始化容量** |
| MCMX | **元空间** 的 **最大容量** |
| MC | **元空间** 当前 **新生成** 的容量 |
| CCSMN | **最小** 压缩类空间大小 |
| CCSMX | **最大** 压缩类空间大小 |
| CCSC | **当前** 压缩类空间大小 |
| YGC | 从应用程序启动到采样时 **年轻代** 中的 gc 次数 |
| FGC | 从应用程序启动到采样时 **老年代** 中的 gc 次数 |
### **2.5. gcmetacapacity**
显示 **元空间**(metaspace)中 **对象** 的信息及其占用量。
```plain text
$ jstat -gcmetacapacity 8615
MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT
0.0 1079296.0 35456.0 0.0 1048576.0 4992.0 5 2 0.075 0.131
参数列表及含义如下:
| 参数 | 参数含义 |
|---|---|
| MCMN | 最小 元数据空间容量 |
| MCMX | 最大 元数据空间容量 |
| MC | 当前 元数据空间容量 |
| CCSMN | 最小压缩 类空间容量 |
| CCSMX | 最大压缩 类空间容量 |
| CCSC | 当前 压缩类空间容量 |
| YGC | 从应用程序启动到采样时 年轻代 中 gc 次数 |
| FGC | 从应用程序启动到采样时 老年代 中 gc 次数 |
| FGCT | 从应用程序启动到采样时 老年代 gc 所用时间 |
| GCT | 从应用程序启动到采样时 gc 用的 总时间 |
2.6. gcnew
显示 年轻代对象 的相关信息,包括两个 survivor 区和 一个 Eden 区。
```plain text $ jstat -gcnew 8615 S0C S1C S0U S1U TTv MTT DSS EC EU YGC YGCT 20480.0 10752.0 0.0 0.0 6 15 20480.0 262144.0 131406.0 5 0.056
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
参数列表及含义如下:
| 参数 | 参数含义 |
| --- | --- |
| S0C | 年轻代中第一个 survivor 的容量 |
| S1C | 年轻代中第二个 survivor 的容量 |
| S0U | 年轻代中第一个 survivor 目前已使用空间 |
| S1U | 年轻代中第二个 survivor 目前已使用空间 |
| TT | 持有次数限制 |
| MTT | 最大持有次数限制 |
| DSS | 期望的 **幸存区** 大小 |
| EC | 年轻代中 Eden 的容量 |
| EU | 年轻代中 Eden 目前已使用空间 |
| YGC | 从应用程序启动到采样时 **年轻代** 中 gc **次数** |
| YGCT | 从应用程序启动到采样时 **年轻代** 中 gc **所用时间** |
### **2.7. gcnewcapacity**
查看 **年轻代** 对象的信息及其占用量。
```plain text
$ jstat -gcnewcapacity 8615
NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC
87040.0 1397760.0 372736.0 465920.0 20480.0 465920.0 10752.0 1396736.0 262144.0 5 2
参数列表及含义如下:
| 参数 | 参数含义 |
|---|---|
| NGCMN | 年轻代中初始化(最小)的大小 |
| NGCMX | 年轻代的最大容量 |
| NGC | 年轻代中当前的容量 |
| S0CMX | 年轻代中第一个 survivor 的最大容量 |
| S0C | 年轻代中第一个 survivor的容量 |
| S1CMX | 年轻代中第二个 survivor 的最大容量 |
| S1C | 年轻代中第二个 survivor 的容量 |
| ECMX | 年轻代中 Eden 的最大容量 |
| EC | 年轻代中 Eden 的容量 |
| YGC | 从应用程序启动到采样时 年轻代 中 gc 次数 |
| FGC | 从应用程序启动到采样时 老年代 中 gc 次数 |
2.8. gcold
显示 老年代对象 的相关信息。
```plain text $ jstat -gcold 8615 MC MU CCSC CCSU OC OU YGC FGC FGCT GCT 35456.0 33931.0 4992.0 4582.0 165376.0 24093.7 5 2 0.075 0.131
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
参数列表及含义如下:
| 参数 | 参数含义 |
| --- | --- |
| MC | **元空间**(metaspace)的容量 |
| MU | **元空间**(metaspace)目前已使用空间 |
| CCSC | 压缩类空间大小 |
| CCSU | 压缩类空间 **使用** 大小 |
| OC | **老年代** 的容量 |
| OU | **老年代** 目前已使用空间 |
| YGC | 从应用程序启动到采样时 **年轻代** 中 gc 次数 |
| FGC | 从应用程序启动到采样时 **老年代** 中 gc 次数 |
| FGCT | 从应用程序启动到采样时 **老年代** gc **所用时间** |
| GCT | 从应用程序启动到采样时 gc 用的 **总时间** |
### **2.9. gcoldcapacity**
查看 **老年代** 对象的信息及其占用量。
```plain text
$ jstat -gcoldcapacity 8615
OGCMN OGCMX OGC OC YGC FGC FGCT GCT
175104.0 2796544.0 165376.0 165376.0 5 2 0.075 0.131
参数列表及含义如下:
| 参数 | 参数含义 |
|---|---|
| OGCMN | 老年代 中初始化(最小)的大小 |
| OGCMX | 老年代 的最大容量 |
| OGC | 老年代 当前新生成的容量 |
| OC | 老年代 的容量 |
| YGC | 从应用程序启动到采样时 年轻代 中 gc 的次数 |
| FGC | 从应用程序启动到采样时 老年代 中 gc 的次数 |
| FGCT | 从应用程序启动到采样时 老年代 中 gc 所用时间 |
| GCT | 从应用程序启动到采样时 gc 用的 总时间 |
2.10. gcutil
显示 垃圾回收(gc)过程中的信息,包括各个 内存的使用占比,垃圾回收 时间 和回收 次数。
```plain text $ jstat -gcutil 8615 S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 0.00 50.13 14.57 95.70 91.79 5 0.056 2 0.075 0.131
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
参数列表及含义如下:
| 参数 | 参数含义 |
| --- | --- |
| S0 | 年轻代中 **第一个** survivor 区 **已使用** 的占当前容量百分比 |
| S1 | 年轻代中 **第二个** survivor 区 **已使用** 的占当前容量百分比 |
| E | 年轻代中 Eden 区 **已使用** 的占当前容量百分比 |
| O | **老年代** 中 **已使用** 的占当前容量百分比 |
| M | **元空间**(metaspace)中 **已使用** 的占当前容量百分比 |
| YGC | 从应用程序启动到采样时 **年轻代** 中 gc **次数** |
| YGCT | 从应用程序启动到采样时 **年轻代** 中 gc **所用时间** |
| FGC | 从应用程序启动到采样时 **老年代** gc **次数** |
| FGCT | 从应用程序启动到采样时 **老年代** gc **所用时间** |
| GCT | 从应用程序启动到采样时 gc 用的 **总时间** |
### **3. jmap堆内存统计工具**
jmap (JVM Memory Map) 命令用来查看 **堆内存** 使用状况,一般结合 jhat 使用,用于生成 heap dump 文件。jmap 不仅能生成 dump 文件,还可以查询 finalize **执行队列**、Java **堆** 和 **元空间** metaspace 的详细信息,如当前 **使用率**、当前使用的是哪种 **收集器** 等等。
```plain text
如果不使用这个命令,还可以使用 -XX:+HeapDumpOnOutOfMemoryError 参数来让虚拟机出现 OOM 的时候,自动生成 dump 文件。
命令格式如下:
```plain text Usage: jmap [option]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
参数含义如下:
- pid:本地 jvm 服务的进程 ID;
- executable core:打印 **堆栈跟踪**
的核心文件;
- remote server IP/hostname:远程 debug 服务的 **主机名**
或 IP 地址;
- server id:远程 debug 服务的 **进程**
ID。
参数选项说明如下:
| 参数 | 参数含义 |
| --- | --- |
| heap | 显示 **堆** 中的摘要信息 |
| histo | 显示 **堆** 中对象的统计信息 |
| histo[:live] | 只显示 **堆** 中 **存活对象** 的统计信息 |
| clstats | 显示 **类加载** 的统计信息 |
| finalizerinfo | 显示在 F-Queue **队列** 等待 Finalizer 线程执行 finalizer 方法的对象 |
| dump | 导出内存转储快照 |
注意:dump 内存快照分析基本上包含了 histo、clstats、finalizerinfo 等功能。
### **3.1. heap**
显示 **堆** 中的摘要信息。包括 **堆内存** 的使用情况,正在使用的 GC **算法**、**堆配置参数** 和 **各代中堆内存** 使用情况。可以用此来判断内存目前的 **使用情况** 以及 **垃圾回收** 情况。
```plain text
$ jmap -heap 11368
Attaching to process ID 11368, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.101-b13
using thread-local object allocation.
Parallel GC with 2 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 2684354560 (2560.0MB)
NewSize = 1073741824 (1024.0MB)
MaxNewSize = 1073741824 (1024.0MB)
OldSize = 1610612736 (1536.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 = 852492288 (813.0MB)
used = 420427144 (400.95056915283203MB)
free = 432065144 (412.04943084716797MB)
49.31741317993014% used
From Space:
capacity = 113770496 (108.5MB)
used = 2299712 (2.19317626953125MB)
free = 111470784 (106.30682373046875MB)
2.021360617079493% used
To Space:
capacity = 107479040 (102.5MB)
used = 0 (0.0MB)
free = 107479040 (102.5MB)
0.0% used
PS Old Generation
capacity = 1610612736 (1536.0MB)
used = 50883368 (48.526161193847656MB)
free = 1559729368 (1487.4738388061523MB)
3.1592552860577903% used
27595 interned Strings occupying 3138384 bytes.
这里主要对 heap configuration 的参数列表说明一下:
| 参数 | 对应启动参数 | 参数含义 |
|---|---|---|
| MinHeapFreeRatio | -XX:MinHeapFreeRatio | JVM堆最小空闲比率(default 40) |
| MaxHeapFreeRatio | -XX:MaxHeapFreeRatio | JVM堆最大空闲比率(default 70) |
| MaxHeapSize | XX:Xmx | JVM堆的最大大小 |
| NewSize | -XX:NewSize | JVM堆新生代的默认(初始化)大小 |
| MaxNewSize | -XX:MaxNewSize | JVM堆新生代的最大大小 |
| OldSize | -XX:OldSize | JVM堆老年代的默认(初始化)大小 |
| NewRatio | -XX:NewRatio | JVM堆新生代和老年代的大小比例 |
| SurvivorRatio | -XX:SurvivorRatio | JVM堆年轻代中Eden区与Survivor区的大小比值 |
| MetaspaceSize | -XX:MetaspaceSize | JVM元空间(metaspace)初始化大小 |
| MaxMetaspaceSize | -XX:MaxMetaspaceSize | JVM元空间(metaspace)最大大小 |
| CompressedClass SpaceSize | -XX:CompressedClass SpaceSize | JVM类指针压缩空间大小, 默认为1G |
| G1HeapRegionSize | -XX:G1HeapRegionSize | 使用G1垃圾回收器时单个Region的大小,取值为1M至32M |
3.2. histo
打印堆的 对象统计,包括 对象实例数、内存大小 等等。因为在 histo:live 前会进行 full gc,如果带上 live 则只统计 活对象。不加 live 的堆大小要大于加 live 堆的大小。
```plain text $ jmap -histo:live 12498 num #instances #bytes class name ———————————————- 1: 50358 7890344 [C 2: 22887 2014056 java.lang.reflect.Method 3: 3151 1485512 [B 4: 49267 1182408 java.lang.String 5: 7836 871384 java.lang.Class 6: 24149 772768 java.util.concurrent.ConcurrentHashMap$Node 7: 20785 482256 [Ljava.lang.Class; 8: 8357 435248 [Ljava.lang.Object; 9: 10035 401400 java.util.LinkedHashMap$Entry 10: 4803 369488 [Ljava.util.HashMap$Node; 11: 10763 344416 java.util.HashMap$Node 12: 5205 291480 java.util.LinkedHashMap 13: 3055 219960 java.lang.reflect.Field 14: 120 193408 [Ljava.util.concurrent.ConcurrentHashMap$Node; 15: 11224 179584 java.lang.Object 16: 1988 146152 [Ljava.lang.reflect.Method; 17: 3036 145728 org.aspectj.weaver.reflect.ShadowMatchImpl 18: 1771 141680 java.lang.reflect.Constructor 19: 4903 117672 org.springframework.core.MethodClassKey 20: 3263 104416 java.lang.ref.WeakReference 21: 2507 100280 java.lang.ref.SoftReference 22: 2523 97600 [I 23: 3036 97152 org.aspectj.weaver.patterns.ExposedState 24: 2072 95280 [Ljava.lang.String; 25: 954 91584 org.springframework.beans.GenericTypeAwarePropertyDescriptor 26: 1633 91448 java.lang.Class$ReflectionData 27: 3142 90520 [Z 28: 1671 80208 java.util.HashMap 29: 3244 77856 java.util.ArrayList 30: 3037 72880 [Lorg.aspectj.weaver.ast.Var; 31: 1809 72360 java.util.WeakHashMap$Entry 32: 1967 62944 java.util.LinkedList
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
其中,class name 是 **对象类型**,对象 **缩写类型** 与 **真实类型** 的对应说明如下:
| 对象缩写类型 | 对象真实类型 |
| --- | --- |
| B | byte |
| C | char |
| D | double |
| F | float |
| I | int |
| J | long |
| Z | boolean |
| [ | 数组,如[I表示int[] |
| [L+类名 | 其他对象 |
### **3.3. dump**
dump 用于导出内存转储快照。常用的方式是通过 jmap 把进程 **内存使用情况** dump 到文件中,再用 jhat 分析查看。jmap 进行 dump 的命令格式如下:
```plain text
jmap -dump:format=b,file=dumpFileName
参数含义如下:
| 参数 | 参数含义 |
|---|---|
| dump | 堆到文件 |
| format | 指定输出格式 |
| live | 指明是活着的对象 |
| file | 指定文件名 |
通过 jmap 导出 内存快照,文件命名为 dump.dat:
```plain text jmap -dump:format=b,file=dump.dat 12498 Dumping heap to /Users/XXX/dump.dat … Heap dump file created
1
2
3
4
5
6
7
8
9
导出的 dump 文件可以通过 MAT、VisualVM 和 jhat 等工具查看分析,后面会详细介绍。
### **4. jhat堆快照分析工具**
jhat(JVM Heap Analysis Tool)命令通常与 jmap 搭配使用,用来分析 jmap 生成的 dump。jhat 内置了一个微型的 HTTP/HTML **服务器**,生成 dump 的分析结果后,可以在浏览器中查看。
```plain text
注意:一般不会直接在 服务器 上 进行分析,因为使用 jhat 是一个 耗时 并且 耗费硬件资源 的过程,一般的做法是,把 服务器 生成的 dump 文件复制到 本地 或 其他机器 上进行分析。
命令格式如下:
```plain text Usage: jhat [-stack