目录
一、jmap命令
1、jmap 命令介绍
2、生成堆内存快照
3、输出堆内存使用情况
4、输出实例和类的详细信息
4.1、查看大对象
4.1、查看对象数最多的对象,并按降序排序输出
4.3、查看占用内存最多的对象,并按降序排序输出
5、显示ClassLoader信息
6、输出Finalizer队列
二、jstat 命令
1. jstat介绍及语法
1.1 .什么是jstat?
1.2. jstat语法及参数说明
2、常用命令
2.1 .-class:显示加载 class 数量及所占空间
2.2 .-compiler:显示VM实时编译的数量
2.3. -gc:显示gc的次数及时间
2.4. -gccapacity:显示VM内存中三代(young/old/perm)对象的使用和占用大小
2.5. -gcmetacapacity:显示元数据空间统计
2.6. -gcnew:显示年轻代对象的信息
2.7. -gcnewcapacity:显示年轻代对象的信息及其占用量
2.8. -gcold:显示老年代对象的信息
2.9.-gcoldcapacity:显示老年代对象的信息及其占用量
2.10. -gcutil:统计gc信息百分比
2.11. -gccause:显示最近一次GC统计和原因
2.12. -printcompilation:JVM编译方法统计
三、远程监控
一、jmap命令
1、jmap 命令介绍
jmap是JDK自带的一个命令行工具,它可以生成并输出Java堆内存使用情况的快照,以及实例和类的详细信息。这个工具通常用于分析Java应用程序的内存使用情况和性能瓶颈。
下面是一些常用的jmap命令:
2、生成堆内存快照
jmap -dump:file=heap.bin <pid>
[root@ph jboss]# jps
1 Bootstrap
22617 Jps
[root@ph jboss]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Nov17 ? 01:20:33 /usr/lib/jvm/java/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.u
root 22582 0 0 11:14 pts/0 00:00:00 bash
root 22639 22582 0 11:15 pts/0 00:00:00 ps -ef
[root@ph jboss]# jmap -dump:file=heap.bin 1
Dumping heap to /opt/jboss/heap.bin ...
Heap dump file created
[root@ph jboss]# ls
heap.bin
[root@ph jboss]# pwd
/opt/jboss
[root@ph jboss]#
这个命令将会生成一个Java堆内存快照,并保存到指定的文件中。其中,<pid>
是目标Java进程的进程ID。你可以使用jps命令来获取Java进程的进程ID。
3、输出堆内存使用情况
# 示例
jmap -heap <pid>
[root@ph jboss]# jmap -heap 1
Attaching to process ID 1, please wait...
Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process: ptrace(PTRACE_ATTACH, ..) failed for 1: Operation not permitted
sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process: ptrace(PTRACE_ATTACH, ..) failed for 1: Operation not permitted
at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$LinuxDebuggerLocalWorkerThread.execute(LinuxDebuggerLocal.java:163)
at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.attach(LinuxDebuggerLocal.java:278)
at sun.jvm.hotspot.HotSpotAgent.attachDebugger(HotSpotAgent.java:671)
at sun.jvm.hotspot.HotSpotAgent.setupDebuggerLinux(HotSpotAgent.java:611)
at sun.jvm.hotspot.HotSpotAgent.setupDebugger(HotSpotAgent.java:337)
at sun.jvm.hotspot.HotSpotAgent.go(HotSpotAgent.java:304)
at sun.jvm.hotspot.HotSpotAgent.attach(HotSpotAgent.java:140)
at sun.jvm.hotspot.tools.Tool.start(Tool.java:185)
at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
at sun.jvm.hotspot.tools.HeapSummary.main(HeapSummary.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.tools.jmap.JMap.runTool(JMap.java:201)
at sun.tools.jmap.JMap.main(JMap.java:130)
Caused by: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process: ptrace(PTRACE_ATTACH, ..) failed for 1: Operation not permitted
at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.attach0(Native Method)
at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.access$100(LinuxDebuggerLocal.java:62)
at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$1AttachTask.doit(LinuxDebuggerLocal.java:269)
at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$LinuxDebuggerLocalWorkerThread.run(LinuxDebuggerLocal.java:138)
[root@ph jboss]#
这个命令将会输出Java堆内存的使用情况,包括堆大小、已用空间、可用空间等信息。这些信息对于分析Java应用程序的内存使用情况非常有用。
option:命令选项,常用选项如下:
- -heap:打印 Java 堆概要信息,包括使用的 GC 算法、堆配置参数和各代中堆内存使用情况;
- -histo[:live]: 打印 Java 堆中对象直方图,通过该图可以获取每个 class 的对象数目,占用内存大小和类全名信息,带上 :live,则只统计活着的对象;
- -permstat 打印永久代统计信息;
- -finalizerinfo 打印等待回收的对象信息
- -dump: 以 hprof 二进制格式将 Java 堆信息输出到文件内,该文件可以用 JProfiler、VisualVM 或 jhat 等工具查看;
dump-options 选项:
- live 只输出活着的对象,不指定则输出堆中所有对象
- format=b 指定输出格式为二进制
- file= 指定文件名及文件存储位置,例如:jmap -dump:live,format=b,file=D:\heap.bin
- -F 与-dump: 或 -histo 一起使用,当没有响应时,强制执行;注意:不支持live子选项
- pid:进程id
4、输出实例和类的详细信息
4.1、查看大对象
# 示例
jmap -histo[:live] <pid>
# 查看 占用内存大小 前10
[root@ph jboss]# jmap -histo 1 |head -10
num #instances #bytes class name
----------------------------------------------
1: 183803 693205272 [I
2: 1912953 186818416 [B
3: 1749844 137592608 [C
4: 2610843 104433720 java.util.TreeMap$Entry
5: 1713468 72514376 [Ljava.lang.Object;
6: 1567614 37622736 java.lang.String
7: 811785 25977120 java.util.HashMap$Node
[root@ph jboss]# jps
1 Bootstrap
22804 Jps
[root@ph jboss]#
这个命令将会输出Java堆中所有实例和类的详细信息。如果添加了:live
参数,则只输出活动的对象信息。这些信息对于定位Java应用程序中的内存泄漏问题非常有用。
4.1、查看对象数最多的对象,并按降序排序输出
jmap -histo <pid>|grep alibaba|sort -k 2 -g -r|less
4.3、查看占用内存最多的对象,并按降序排序输出
jmap -histo <pid>|grep alibaba|sort -k 3 -g -r|less
5、显示ClassLoader信息
# 示例
jmap -clstats <pid>
[root@ph jboss]# jmap -clstats 1
Attaching to process ID 1, please wait...
Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process: ptrace(PTRACE_ATTACH, ..) failed for 1: Operation not permitted
sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process: ptrace(PTRACE_ATTACH, ..) failed for 1: Operation not permitted
at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$LinuxDebuggerLocalWorkerThread.execute(LinuxDebuggerLocal.java:163)
at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.attach(LinuxDebuggerLocal.java:278)
at sun.jvm.hotspot.HotSpotAgent.attachDebugger(HotSpotAgent.java:671)
at sun.jvm.hotspot.HotSpotAgent.setupDebuggerLinux(HotSpotAgent.java:611)
at sun.jvm.hotspot.HotSpotAgent.setupDebugger(HotSpotAgent.java:337)
at sun.jvm.hotspot.HotSpotAgent.go(HotSpotAgent.java:304)
at sun.jvm.hotspot.HotSpotAgent.attach(HotSpotAgent.java:140)
at sun.jvm.hotspot.tools.Tool.start(Tool.java:185)
这个命令将会输出Java应用程序中ClassLoader的详细信息,包括ClassLoader的类型、名称和加载的类数量等信息。这些信息对于分析Java应用程序的类加载情况非常有用。
6、输出Finalizer队列
示例:
jmap -finalizerinfo <pid>
[root@ph jboss]# jmap -finalizerinfo 1
Attaching to process ID 1, please wait...
Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process: ptrace(PTRACE_ATTACH, ..) failed for 1: Operation not permitted
sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process: ptrace(PTRACE_ATTACH, ..) failed for 1: Operation not permitted
at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$LinuxDebuggerLocalWorkerThread.execute(LinuxDebuggerLocal.java:163)
at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.attach(LinuxDebuggerLocal.java:278)
at sun.jvm.hotspot.HotSpotAgent.attachDebugger(HotSpotAgent.java:671)
at sun.jvm.hotspot.HotSpotAgent.setupDebuggerLinux(HotSpotAgent.java:611)
at sun.jvm.hotspot.HotSpotAgent.setupDebugger(HotSpotAgent.java:337)
at sun.jvm.hotspot.HotSpotAgent.go(HotSpotAgent.java:304)
at sun.jvm.hotspot.HotSpotAgent.attach(HotSpotAgent.java:140)
这个命令将会输出Java应用程序中Finalizer队列的详细信息,包括在队列中等待Finalizer线程执行的对象数量、占用的内存大小等信息。这些信息对于定位Java应用程序中的内存泄漏问题非常有用。
二、jstat 命令
1. jstat介绍及语法
1.1 .什么是jstat?
jstat 是 JDK 提供的一个命令行工具,用于监视 Java 虚拟机(JVM)的各种统计信息。
jstat 位于 java 安装目录的 bin 目录下,主要利用 JVM 内建的指令对 java 应用程序的资源和性能进行实时的监控,包括对 JVM 内存中各种堆内存(Heap size)和非堆内存(No heap size)的大小及其内存使用量,以及垃圾回收状况的监控。
1.2. jstat语法及参数说明
jstat 语法格式:jstat <-命令选项> [-t] [-h<lines>] <pid> [<间隔时间/毫秒> [查询次数]]
(<>
表示必填,[]
表示选填)
[root@sddi-8 jboss]# jstat -help
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: 用于指定输出多少次记录,缺省则会一直打印。
其中,-option
可以从下面常用命令中选择。
2、常用命令
为方便展示,以下截图均为 docker 容器中执行结果,容器中只启动了 Bootstrap
一个 java 程序,pid 为 1。
[root@sddi-8 jboss]# jps
1 Bootstrap
108307 Jps
[root@sddi-8 jboss]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 57 08:33 ? 00:34:23 /usr/lib/jvm/java/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava
root 52170 0 0 09:19 pts/0 00:00:00 bash
root 109438 52170 0 09:32 pts/0 00:00:00 ps -ef
2.1 .-class:显示加载 class 数量及所占空间
[root@sddi-8 jboss]# jstat -class 1
Loaded Bytes Unloaded Bytes Time
23462 52928.7 0 0.0 22.05
信息说明:
- Loaded:加载类的数量
- Bytes:加载类的size,单位为Byte
- Unloaded:卸载类的数目
- Bytes:卸载类的size,单位为Byte
- Time:加载与卸载类花费的时间
2.2 .-compiler:显示VM实时编译的数量
[root@sddi-8 jboss]# jstat -compiler 1
Compiled Failed Invalid Time FailedType FailedMethod
42505 7 0 300.77 1 org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding computeId
信息说明:
- Compiled:编译任务执行数量
- Failed:编译任务执行失败数量
- Invalid:编译任务执行失效数量
- Time:编译任务消耗时间
- FailedType:最后一个编译失败任务的类型
- FailedMethod:最后一个编译失败任务所在的类及方法
2.3. -gc:显示gc的次数及时间
[root@sddi-8 jboss]# jstat -gc 1
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
152064.0 90112.0 0.0 89968.6 20679680.0 9365152.6 41943040.0 10219481.3 207616.0 192971.8 0.0 0.0 115 15.473 5 5.966 21.439
[root@sddi-8 jboss]#
信息说明:
- S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
- S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
- S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
- S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
- EC:年轻代中Eden(伊甸园)的容量 (字节)
- EU:年轻代中Eden(伊甸园)目前已使用空间 (字节)
- OC:老年代的容量 (字节)
- OU:老年代目前已使用空间 (字节)
- MC:metaspace(元空间)的容量 (字节)
- MU:metaspace(元空间)目前已使用空间 (字节)
- CCSC:当前压缩类空间的容量 (字节)
- CCSU:当前压缩类空间目前已使用空间 (字节)
- YGC:从应用程序启动到采样时年轻代中gc次数
- YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)
- FGC:从应用程序启动到采样时老年代(全gc)gc次数
- FGCT:从应用程序启动到采样时老年代(全gc)gc所用时间(s)
- GCT:从应用程序启动到采样时gc用的总时间(s)
2.4. -gccapacity:显示VM内存中三代(young/old/perm)对象的使用和占用大小
[root@sddi-8 jboss]# jstat -gccapacity 1
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC
20971520.0 20971520.0 20971520.0 152064.0 90112.0 20679680.0 41943040.0 41943040.0 41943040.0 41943040.0 0.0 208896.0 207616.0 0.0 0.0 0.0 115 5
信息说明:
- NGCMN:年轻代(young)中初始化(最小)的大小(字节)
- NGCMX:年轻代(young)的最大容量 (字节)
- NGC:年轻代(young)中当前的容量 (字节)
- S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
- S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
- EC:年轻代中Eden(伊甸园)的容量 (字节)
- OGCMN:老年代中初始化(最小)的容量大小 (字节)
- OGCMX:老年代的最大容量(字节)
- OGC:老年代当前新生成的容量 (字节)
- OC:老年代的容量 (字节)
- MCMN:metaspace(元空间)中初始化(最小)的大小 (字节)
- MCMX:metaspace(元空间)的最大容量 (字节)
- MC:metaspace(元空间)当前新生成的容量 (字节)
- CCSMN:最小压缩类空间大小
- CCSMX:最大压缩类空间大小
- CCSC:当前压缩类空间大小
- YGC:从应用程序启动到采样时年轻代中gc次数
- FGC:从应用程序启动到采样时老年代(全gc)gc次数
2.5. -gcmetacapacity:显示元数据空间统计
[root@sddi-8 jboss]# jstat -gcmetacapacity 1
MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT
0.0 208896.0 208128.0 0.0 0.0 0.0 116 5 5.966 21.516
信息说明:
- MCMN:最小元数据容量
- MCMX:最大元数据容量
- MC:当前元数据空间大小
- CCSMN:最小压缩类空间大小
- CCSMX:最大压缩类空间大小
- CCSC:当前压缩类空间大小
- YGC:从应用程序启动到采样时年轻代中gc次数
- FGC:从应用程序启动到采样时老年代(全gc)gc次数
- FGCT:从应用程序启动到采样时老年代(全gc)gc所用时间(s)
- GCT:从应用程序启动到采样时gc用的总时间(s)
2.6. -gcnew:显示年轻代对象的信息
[root@sddi-8 jboss]# jstat -gcnew 1
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
152064.0 160256.0 100551.4 0.0 8 15 160256.0 20651008.0 5289164.6 116 15.550
信息说明:
- S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
- S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
- S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
- S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
- TT:持有次数限制
- MTT:最大持有次数限制
- DSS:期望的幸存区大小
- EC:年轻代中Eden(伊甸园)的容量 (字节)
- EU:年轻代中Eden(伊甸园)目前已使用空间 (字节)
- YGC:从应用程序启动到采样时年轻代中gc次数
- YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)
2.7. -gcnewcapacity:显示年轻代对象的信息及其占用量
[root@sddi-8 jboss]# jstat -gcnewcapacity 1
NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC
20971520.0 20971520.0 20971520.0 6990336.0 152064.0 6990336.0 160256.0 20970496.0 20651008.0 116 5
信息说明:
- NGCMN:年轻代(young)中初始化(最小)的大小(字节)
- NGCMX:年轻代(young)的最大容量 (字节)
- NGC:年轻代(young)中当前的容量 (字节)
- S0CMX:年轻代中第一个survivor(幸存区)的最大容量 (字节)
- S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
- S1CMX:年轻代中第二个survivor(幸存区)的最大容量 (字节)
- S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
- ECMX:年轻代中Eden(伊甸园)的最大容量 (字节)
- EC:年轻代中Eden(伊甸园)的容量 (字节)
- YGC:从应用程序启动到采样时年轻代中gc次数
- FGC:从应用程序启动到采样时old代(全gc)gc次数
2.8. -gcold:显示老年代对象的信息
[root@sddi-8 jboss]# jstat -gcold 1
MC MU CCSC CCSU OC OU YGC FGC FGCT GCT
208128.0 193286.7 0.0 0.0 41943040.0 10219489.3 116 5 5.966 21.516
信息说明:
- MC:metaspace(元空间)的容量 (字节)
- MU:metaspace(元空间)目前已使用空间 (字节)
- CCSC:压缩类空间大小
- CCSU:压缩类空间使用大小
- OC:Old代的容量 (字节)
- OU:Old代目前已使用空间 (字节)
- YGC:从应用程序启动到采样时年轻代中gc次数
- FGC:从应用程序启动到采样时old代(全gc)gc次数
- FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT:从应用程序启动到采样时gc用的总时间(s)
2.9.-gcoldcapacity:显示老年代对象的信息及其占用量
[root@sddi-8 jboss]# jstat -gcoldcapacity 1
OGCMN OGCMX OGC OC YGC FGC FGCT GCT
41943040.0 41943040.0 41943040.0 41943040.0 117 5 5.966 21.551
信息说明:
- OGCMN:old代中初始化(最小)的大小 (字节)
- OGCMX:old代的最大容量(字节)
- OGC:old代当前新生成的容量 (字节)
- OC:Old代的容量 (字节)
- YGC:从应用程序启动到采样时年轻代中gc次数
- FGC:从应用程序启动到采样时old代(全gc)gc次数
- FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT:从应用程序启动到采样时gc用的总时间(s)
2.10. -gcutil:统计gc信息百分比
[root@sddi-8 jboss]# jstat -gcutil 1
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 99.82 57.50 24.37 92.90 - 117 15.585 5 5.966 21.551
信息说明:
- S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
- S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
- E:年轻代中Eden(伊甸园)已使用的占当前容量百分比
- O:old代已使用的占当前容量百分比
- M:元数据区已使用的占当前容量百分比
- CCS:压缩类空间已使用的占当前容量百分比
- YGC :从应用程序启动到采样时年轻代中gc次数
- YGCT :从应用程序启动到采样时年轻代中gc所用时间(s)
- FGC :从应用程序启动到采样时old代(全gc)gc次数
- FGCT :从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT:从应用程序启动到采样时gc用的总时间(s)
2.11. -gccause:显示最近一次GC统计和原因
[root@sddi-8 jboss]# jstat -gccause 1
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC
69.94 0.00 17.64 24.37 92.80 - 118 15.651 5 5.966 21.616 Allocation Failure No GC
信息说明:
- LGCC:最后一次GC原因
- GCC:当前GC原因(No GC 为当前没有执行GC)
2.12. -printcompilation:JVM编译方法统计
[root@sddi-8 jboss]# jstat -printcompilation 1
Compiled Size Type Method
46493 400 1 org/springframework/core/convert/TypeDescriptor valueOf
信息说明:
- Compiled:编译任务的数目
- Size:方法生成的字节码的大小
- Type:编译类型
- Method:类名和方法名用来标识编译的方法。类名使用/做为一个命名空间分隔符。方法名是给定类中的方法。上述格式是由-XX:+PrintComplation选项进行设置的
三、远程监控
与 jps
一样,jstat
也支持远程监控,同样需要开启安全授权,类似 jps。