【JVM】05. 性能调优(一):常用监控命令介绍
JVM 性能调优是确保Java应用程序高效运行的关键。在本专题中,我们将深入探讨JVM性能调优的各个方面,包括常见的、诊断工具、性能问题以及调优策略。作为开篇,本文将介绍几个常用的JVM监控命令:
jps
、jmap
、jinfo
、jstack
和jstat
,这些命令是性能调优和故障排查的重要工具。
1 jps
jps
(Java Virtual Machine Process Status Tool)用于列出当前系统上所有的 JVM 进程,对于管理和监控运行中的 Java 应用程序非常有用,尤其是当你需要快速查找某个 Java 应用程序的进程 ID 或了解其启动参数时。
2 jmap
jmap(Memory Map for Java)主要用于生成 JVM 的堆转储快照(heap dump)。这个快照包含了 JVM 堆中所有对象的实例信息,在排查内存泄漏和分析内存使用情况时非常有用。通过 jmap
生成的堆转储文件,可以使用其他内存分析工具(如 VisualVM)进行深入分析。
2.1.1 查看堆内存详细信息
jmap [pid]
:打印指定进程 ID 的 Java 堆的详细信息。
2.2 查看堆内存概要信息
jmap -heap [pid]
:打印 Java 堆的概要信息,包括堆的配置(如 Eden、Survivor、Old 区的大小)和当前使用情况。
2.3 堆内存dump
jmap -dump:format=b,file=<heapdump>.hprof [pid]
:生成指定进程 ID 的堆转储,并将其保存到指定的文件中。format=b
表示生成二进制格式的堆转储。
也可以设置内存溢出自动导出dump文件(内存很大的时候,可能会导不出来)
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./jvm.dump (导出路径)
示例代码:
public class OOMTest {
public static List<Object> list = new ArrayList<>();
// JVM设置
// -Xms5M -Xmx5M -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./jvm.dump
public static void main(String[] args) {
List<Object> list = new ArrayList<>();
int i = 0;
int j = 0;
while (true) {
list.add(new User(i++, UUID.randomUUID().toString()));
new User(j--, UUID.randomUUID().toString());
}
}
static class User {
private int id;
private String name;
public User(){}
public User(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
可以用jvisualvm命令工具导入该dump文件查看:
2.4 查看对象的内存使用
jmap -histo [pid]
:查看历史生成的实例,按对象数量和大小排序。
jmap -histo:live [pid]
:查看当前存活的实例,按对象数量和大小排序,执行过程中可能会触发一次full gc。
- num:序号
- instances:实例数量
- bytes:占用空间大小
- class name:类名称
3 jinfo
jinfo
是用于查看和修改 JVM 的配置参数。这些参数通常在 JVM 启动时设置,但在某些情况下,我们可能需要在不重启 JVM 的情况下查看或修改这些参数。
3.1 查看 JVM 参数
jinfo [pid]
:打印指定进程 ID 的 JVM 的所有配置参数及其当前值,包括堆大小、垃圾收集器等。
jinfo -flags [pid]
:打印 JVM 的启动时的命令行参数,包括 JVM 选项和应用程序参数。
jinfo -flag <flag_name> [pid]
:打印指定名称的 JVM 参数的当前值。例如,jinfo -flag MaxHeapSize [pid]
将打印堆内存最大配置。
3.2 查看 JVM 系统属性
jinfo -sysprops [pid]
:打印 JVM 进程的所有系统属性(通过 System.getProperties()
获取的内容)
3.3 修改 JVM 参数
jinfo -flag <flag_name> <flag_value> [pid]
:动态修改指定名称的 JVM 参数的值。这在某些情况下非常有用,比如调整堆内存大小或启用/禁用垃圾收集器的某些特性。需要注意的是,并非所有的 JVM 参数都支持动态修改。有些参数只能在 JVM 启动时设置,而有些参数虽然可以动态修改,但修改后的效果可能需要一段时间才能体现,或者需要触发某些事件(如垃圾收集)才能生效。因此,在使用 jinfo
修改参数时,需要参考具体的 JVM 参数文档,了解其行为和限制。
4 jstack
jstack(Stack Trace for Java)用于生成 JVM 中线程的当前堆栈跟踪信息。这个工具对于分析应用程序的线程状态、诊断死锁问题以及查找导致程序长时间挂起的原因非常有用。
4.1 线程堆栈跟踪
jstack [pid]
:打印指定进程 ID 的 JVM 中所有线程的堆栈跟踪信息。
4.2 死锁检测报告
jstack -l [pid]
:除了打印所有线程的堆栈跟踪外,还会检测并报告线程死锁情况。
5 jstats
jstat
用于收集和查看 Java 虚拟机(JVM)的运行时统计信息。这些统计信息包括但不限于堆内存使用情况、垃圾收集器的行为、类加载器的状态、线程使用情况等。
5.1 查看堆内存使用情况
jstat -gc [pid]
:垃圾回收统计。打印 JVM 的垃圾收集统计信息,包括各代内存的使用量和垃圾收集的次数。
- S0C:第一个幸存区的大小,单位KB
- S1C:第二个幸存区的大小
- S0U:第一个幸存区的使用大小
- S1U:第二个幸存区的使用大小
- EC:伊甸园区的大小
- EU:伊甸园区的使用大小
- OC:老年代大小
- OU:老年代使用大小
- MC:方法区大小(元空间)
- MU:方法区使用大小
- CCSC:压缩类空间大小
- CCSU:压缩类空间使用大小
- YGC:年轻代垃圾回收次数
- YGCT:年轻代垃圾回收消耗时间,单位s
- FGC:老年代垃圾回收次数
- FGCT:老年代垃圾回收消耗时间,单位s
- GCT:垃圾回收消耗总时间,单位s
5.2 查看堆内存增长情况
jstat -gccapacity [pid]
:堆内存统计。显示 JVM 堆内存的容量和使用量。
- NGCMN:新生代最小容量
- NGCMX:新生代最大容量
- NGC:当前新生代容量
- S0C:第一个幸存区大小
- S1C:第二个幸存区的大小
- EC:伊甸园区的大小
- OGCMN:老年代最小容量
- OGCMX:老年代最大容量
- OGC:当前老年代大小
- OC:当前老年代大小
- MCMN:最小元数据容量
- MCMX:最大元数据容量
- MC:当前元数据空间大小
- CCSMN:最小压缩类空间大小
- CCSMX:最大压缩类空间大小
- CCSC:当前压缩类空间大小
- YGC:年轻代gc次数
- FGC:老年代GC次数
5.3 老年代垃圾回收统计
jstat -gcold [pid]
- MC:方法区大小
- MU:方法区使用大小
- CCSC:压缩类空间大小
- CCSU:压缩类空间使用大小
- OC:老年代大小
- OU:老年代使用大小
- YGC:年轻代垃圾回收次数
- FGC:老年代垃圾回收次数
- FGCT:老年代垃圾回收消耗时间
- GCT:垃圾回收消耗总时间
5.4 老年代内存统计
`jstat -gcoldcapacity [pid]
- OGCMN:老年代最小容量
- OGCMX:老年代最大容量
- OGC:当前老年代大小
- OC:老年代大小
- YGC:年轻代垃圾回收次数
- FGC:老年代垃圾回收次数
- FGCT:老年代垃圾回收消耗时间
- GCT:垃圾回收消耗总时间
5.5 新生代垃圾回收统计
jstat -gcnew [pid]
- S0C:第一个幸存区的大小
- S1C:第二个幸存区的大小
- S0U:第一个幸存区的使用大小
- S1U:第二个幸存区的使用大小
- TT:对象在新生代存活的次数
- MTT:对象在新生代存活的最大次数
- DSS:期望的幸存区大小
- EC:伊甸园区的大小
- EU:伊甸园区的使用大小
- YGC:年轻代垃圾回收次数
- YGCT:年轻代垃圾回收消耗时间
5.6 新生代内存统计
jstat -gcnewcapacity [pid]
- NGCMN:新生代最小容量
- NGCMX:新生代最大容量
- NGC:当前新生代容量
- S0CMX:最大幸存1区大小
- S0C:当前幸存1区大小
- S1CMX:最大幸存2区大小
- S1C:当前幸存2区大小
- ECMX:最大伊甸园区大小
- EC:当前伊甸园区大小
- YGC:年轻代垃圾回收次数
- FGC:老年代回收次数
5.7 元空间内存统计
jstat -gcmetacapacity [pid]
- MCMN:最小元数据容量
- MCMX:最大元数据容量
- MC:当前元数据空间大小
- CCSMN:最小压缩类空间大小
- CCSMX:最大压缩类空间大小
- CCSC:当前压缩类空间大小
- YGC:年轻代垃圾回收次数
- FGC:老年代垃圾回收次数
- FGCT:老年代垃圾回收消耗时间
- GCT:垃圾回收消耗总时间
5.8 监控实时的 GC 信息
jstat -gcutil [pid] <interval> <count>
:每隔 <interval>
毫秒打印一次 GC 信息,共打印 <count>
次。
- S0:幸存1区当前使用比例
- S1:幸存2区当前使用比例
- E:伊甸园区使用比例
- O:老年代使用比例
- M:元数据区使用比例
- CCS:压缩使用比例
- YGC:年轻代垃圾回收次数
- FGC:老年代垃圾回收次数
- FGCT:老年代垃圾回收消耗时间
- GCT:垃圾回收消耗总时间
6 结语
在本篇博文中,我们介绍了五个强大的JVM监控命令:jps
、jmap
、jinfo
、jstack
和 jstat
。这些工具为我们提供了洞察Java虚拟机内部运作的能力,是性能调优和故障排查的重要武器。通过这些命令,我们可以有效地监控和管理Java应用程序的运行状态,及时发现并解决潜在的性能问题。
性能调优是一个需要深入理解JVM内部机制的过程,它涉及到内存管理、垃圾收集、线程调度等多个方面。掌握这些命令行工具的使用,只是性能调优旅程的第一步。在后续的文章中,我们将进一步探讨JVM性能调优的深层次话题。
!thumbup
Hello @fangwei! You are The Best!
command: !thumbup is powered by witness @justyy and his contributions are: https://steemyy.com
More commands are coming!