【JVM】05. 性能调优(一):常用监控命令介绍

in #studylast month

JVM 性能调优是确保Java应用程序高效运行的关键。在本专题中,我们将深入探讨JVM性能调优的各个方面,包括常见的、诊断工具、性能问题以及调优策略。作为开篇,本文将介绍几个常用的JVM监控命令:jpsjmapjinfojstackjstat,这些命令是性能调优和故障排查的重要工具。

1 jps

jps(Java Virtual Machine Process Status Tool)用于列出当前系统上所有的 JVM 进程,对于管理和监控运行中的 Java 应用程序非常有用,尤其是当你需要快速查找某个 Java 应用程序的进程 ID 或了解其启动参数时。

jps-1.png

2 jmap

jmap(Memory Map for Java)主要用于生成 JVM 的堆转储快照(heap dump)。这个快照包含了 JVM 堆中所有对象的实例信息,在排查内存泄漏和分析内存使用情况时非常有用。通过 jmap 生成的堆转储文件,可以使用其他内存分析工具(如 VisualVM)进行深入分析。

2.1.1 查看堆内存详细信息

jmap [pid]:打印指定进程 ID 的 Java 堆的详细信息。

jmap-1.png

2.2 查看堆内存概要信息

jmap -heap [pid]:打印 Java 堆的概要信息,包括堆的配置(如 Eden、Survivor、Old 区的大小)和当前使用情况。

jmap-2.png

2.3 堆内存dump

jmap -dump:format=b,file=<heapdump>.hprof [pid]:生成指定进程 ID 的堆转储,并将其保存到指定的文件中。format=b 表示生成二进制格式的堆转储。

也可以设置内存溢出自动导出dump文件(内存很大的时候,可能会导不出来)

  1. -XX:+HeapDumpOnOutOfMemoryError
  2. -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文件查看:

jmap-3.png

2.4 查看对象的内存使用

jmap -histo [pid]:查看历史生成的实例,按对象数量和大小排序。
jmap -histo:live [pid]:查看当前存活的实例,按对象数量和大小排序,执行过程中可能会触发一次full gc。

jmap-4.png

  • 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] 将打印堆内存最大配置。

jinfo-1.png

jinfo-2.png

3.2 查看 JVM 系统属性

jinfo -sysprops [pid]:打印 JVM 进程的所有系统属性(通过 System.getProperties() 获取的内容)

jinfo-3.png

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 中所有线程的堆栈跟踪信息。

jstack-1.png

4.2 死锁检测报告

jstack -l [pid]:除了打印所有线程的堆栈跟踪外,还会检测并报告线程死锁情况。

jstack-2.png

5 jstats

jstat 用于收集和查看 Java 虚拟机(JVM)的运行时统计信息。这些统计信息包括但不限于堆内存使用情况、垃圾收集器的行为、类加载器的状态、线程使用情况等。

5.1 查看堆内存使用情况

jstat -gc [pid]:垃圾回收统计。打印 JVM 的垃圾收集统计信息,包括各代内存的使用量和垃圾收集的次数。

jstats-1.png

  • 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 堆内存的容量和使用量。

jstats-2.png

  • 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]

jstats-3.png

  • MC:方法区大小
  • MU:方法区使用大小
  • CCSC:压缩类空间大小
  • CCSU:压缩类空间使用大小
  • OC:老年代大小
  • OU:老年代使用大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

5.4 老年代内存统计

`jstat -gcoldcapacity [pid]

jstats-4.png

  • OGCMN:老年代最小容量
  • OGCMX:老年代最大容量
  • OGC:当前老年代大小
  • OC:老年代大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

5.5 新生代垃圾回收统计

jstat -gcnew [pid]

jstats-5.png

  • S0C:第一个幸存区的大小
  • S1C:第二个幸存区的大小
  • S0U:第一个幸存区的使用大小
  • S1U:第二个幸存区的使用大小
  • TT:对象在新生代存活的次数
  • MTT:对象在新生代存活的最大次数
  • DSS:期望的幸存区大小
  • EC:伊甸园区的大小
  • EU:伊甸园区的使用大小
  • YGC:年轻代垃圾回收次数
  • YGCT:年轻代垃圾回收消耗时间

5.6 新生代内存统计

jstat -gcnewcapacity [pid]

jstats-6.png

  • NGCMN:新生代最小容量
  • NGCMX:新生代最大容量
  • NGC:当前新生代容量
  • S0CMX:最大幸存1区大小
  • S0C:当前幸存1区大小
  • S1CMX:最大幸存2区大小
  • S1C:当前幸存2区大小
  • ECMX:最大伊甸园区大小
  • EC:当前伊甸园区大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代回收次数

5.7 元空间内存统计

jstat -gcmetacapacity [pid]

jstats-7.png

  • MCMN:最小元数据容量
  • MCMX:最大元数据容量
  • MC:当前元数据空间大小
  • CCSMN:最小压缩类空间大小
  • CCSMX:最大压缩类空间大小
  • CCSC:当前压缩类空间大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

5.8 监控实时的 GC 信息

jstat -gcutil [pid] <interval> <count>:每隔 <interval> 毫秒打印一次 GC 信息,共打印 <count> 次。

jstats-8.png

  • S0:幸存1区当前使用比例
  • S1:幸存2区当前使用比例
  • E:伊甸园区使用比例
  • O:老年代使用比例
  • M:元数据区使用比例
  • CCS:压缩使用比例
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

6 结语

在本篇博文中,我们介绍了五个强大的JVM监控命令:jpsjmapjinfojstackjstat。这些工具为我们提供了洞察Java虚拟机内部运作的能力,是性能调优和故障排查的重要武器。通过这些命令,我们可以有效地监控和管理Java应用程序的运行状态,及时发现并解决潜在的性能问题。

性能调优是一个需要深入理解JVM内部机制的过程,它涉及到内存管理、垃圾收集、线程调度等多个方面。掌握这些命令行工具的使用,只是性能调优旅程的第一步。在后续的文章中,我们将进一步探讨JVM性能调优的深层次话题。

Sort:  

Hello @fangwei! You are The Best!


command: !thumbup is powered by witness @justyy and his contributions are: https://steemyy.com
More commands are coming!

Coin Marketplace

STEEM 0.19
TRX 0.12
JST 0.027
BTC 65368.93
ETH 3415.18
USDT 1.00
SBD 2.54