「JVM」性能调优工具

一、jcmd

1、jcmd 能干嘛?

jcmd 是 Java 命令行工具的一部分,用于执行各种与运行中的 Java 进程相关的诊断和管理任务。它提供了许多有用的操作,可以帮助你监视、管理和诊断 Java 应用程序。以下是 jcmd 工具的一些常见用途:

  1. 列出正在运行的 Java 进程:使用 jcmd -l 命令可以列出系统中当前正在运行的 Java 进程的进程 ID 和主类。
  2. 打印 Java 进程的概要信息:使用 jcmd <pid> VM.native_memory summary 命令可以打印指定 Java 进程的本机内存使用情况的摘要信息。
  3. 导出 Java 进程的堆转储文件:使用 jcmd <pid> GC.heap_dump <filename> 命令可以导出指定 Java 进程的堆转储文件,用于分析内存使用情况。
  4. 查看 Java 进程的线程堆栈:使用 jcmd <pid> Thread.print 命令可以打印指定 Java 进程的线程堆栈信息,用于分析线程问题和死锁情况。
  5. 执行 JVM 命令:使用 jcmd <pid> <command> 命令可以在运行中的 Java 进程上执行各种 JVM 命令,例如 JVM.versionJVM.flags 等。
  6. 执行自定义的诊断命令:你还可以使用 jcmd 工具执行自定义的诊断命令,这些命令是由 Java 应用程序开发者自己实现的,用于特定的应用程序诊断和管理任务。
    总的来说,jcmd 是一个非常强大的工具,可用于监视和调试运行中的 Java 进程,提供了许多有用的功能来帮助你分析和解决 Java 应用程序的性能问题和其他类型的故障。

2、与JVM相关的命令

jcmd 命令是 Java 的诊断命令,用于执行各种与运行中的 Java 进程相关的操作。以下是一些常见的 jcmd 命令:

  1. JVM 状态相关命令
  • VM.flags:显示 JVM 的标志和系统属性。
  • VM.system_properties:显示 JVM 的系统属性。
  • VM.command_line:显示启动 JVM 的命令行参数。
  • VM.version:显示 JVM 的版本信息。
  1. 内存相关命令
  • GC.class_histogram:显示当前堆中各个类的实例数目统计。
  • GC.heap_info:显示堆的使用情况统计信息。
  • GC.run_finalization:手动运行终结器。
  1. 线程和死锁相关命令
  • Thread.print:打印线程堆栈信息。
  • Thread.print -l:打印详细的线程堆栈信息,包括锁持有者和等待条件。
  • Thread.info:显示所有线程的基本信息。
  • Thread.dump:生成线程转储文件。
  1. 性能监控和故障处理命令
  • VM.uptime:显示 JVM 的运行时间。
  • VM.dynlibs:显示加载的动态链接库。
  • ManagementAgent.start_local:启动 JMX 代理以进行远程监控。
  1. JIT 编译器命令
  • Compiler.print_classes:打印已编译类的列表。
  • Compiler.disable:禁用 JIT 编译器。
  • Compiler.enable:启用 JIT 编译器。
  1. 示例
[root@es-node3 /]# jcmd 19566 VM.command_line
19566:
VM Arguments:
jvm_args: -Djava.util.Arrays.useLegacyMergeSort=true -javaagent:/app/agent/skywalking-agent.jar=agent.service_name=community,collector.backend_service=10.11.68.78:31180 -Xmx6g -Xms6g -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M -XX:+UseG1GC -XX:+ParallelRefProcEnabled
java_command: /app/intensive-web/community.jar --spring.profiles.active=prod --spring.cloud.nacos.config.file-extension=properties --spring.cloud.nacos.config.server-addr=10.11.68.77:8848 --spring.cloud.nacos.discovery.server-addr=10.11.68.77:8848 --logging.level.com.alibaba.nacos.client.naming=ERROR
java_class_path (initial): /app/intensive-web/community-intensive-web.jar:/app/agent/skywalking-agent.jar
Launcher Type: SUN_STANDARD

命令解释

这是一个jcmd命令的输出结果,显示了进程ID为19566的Java虚拟机(JVM)的启动参数和主要配置信息。具体内容包括:

  • VM Arguments:JVM的运行参数,包括以下几个:
    • jvm_args:JVM的启动参数,包括使用遗留的合并排序算法、SkyWalking代理的配置、堆内存大小、元数据区大小、垃圾收> 集器的选择等。
    • java_command:Java程序的启动命令,包括应用程序的jar包路径和一些Spring配置参数。
    • java_class_path (initial):Java类路径,包括应用程序的jar包路径和SkyWalking代理的jar包路径。
    • Launcher Type:启动器类型,此处为SUN_STANDARD。

通过这些信息,可以查看应用程序的启动参数和配置,了解JVM的运行情况,进行问题排查和性能优化。
还有许多其他可用的 jcmd 命令,你可以使用 jcmd <PID> help 来查看特定 Java 进程支持的所有命令。请注意,<PID> 是 Java 进程的进程 ID,你需要将其替换为实际的进程 ID。

3、示例

jcmd 命令是 Java 命令行工具的一部分,用于执行各种与运行中的 Java 进程相关的诊断和管理任务。下面是一些常用的 jcmd 命令及其示范用法:

  1. 列出正在运行的 Java 进程
 jcmd -l

示例输出:

 1234 com.example.MyApp
 5678 com.example.OtherApp
  1. 打印 Java 进程的概要信息
 jcmd 1234 VM.native_memory summary

示例输出:

   Native Memory Tracking:
   Total: reserved=100MB, committed=10MB
            ...
  1. 导出 Java 进程的堆转储文件
 jcmd 1234 GC.heap_dump /path/to/dump.hprof

堆转储文件将保存在指定路径 /path/to/dump.hprof

  1. 查看 Java 进程的线程堆栈

    jcmd 1234 Thread.print
    

    示例输出:

    0x00001 Thread-0
    ...
    
  2. 执行 JVM 命令

    jcmd 1234 JVM.version
    

    示例输出:

    JVM version: 11.0.12+7-LTS
    JVM information: OpenJDK 64-Bit Server VM by Oracle Corporation
    
  3. 执行自定义的诊断命令

    jcmd 1234 com.example.MyApp customCommand
    

    这将执行 Java 应用程序中注册的名为 customCommand 的自定义诊断命令。

请注意,以上示例命令中的 1234 是要操作的 Java 进程的进程 ID,你需要将其替换为真实的进程 ID。你可以通过 jcmd -l 命令列出当前正在运行的 Java 进程及其对应的进程 ID。

二、jmap

1、jmap有什么用?

jmap 是 Java 命令行工具中的一个选项,用于生成 Java 应用程序的堆转储快照(Heap Dump Snapshot)。堆转储快照是一个二进制文件,它包含了 Java 应用程序在某个时间点上的内存使用情况。jmap 的主要用途如下:

  1. 内存分析:通过生成堆转储快照,可以获取 Java 应用程序的内存使用情况。您可以使用其他工具(如 VisualVM、MAT 等)打开和分析堆转储文件,了解对象的分配、内存泄漏等问题,以及查找性能优化的机会。
  2. 内存监控:您可以使用 jmap 的 -histo 选项来获取堆转储快照中各个类的实例数量和占用内存大小的统计信息。这对于监控应用程序中的对象分布和内存泄漏问题很有帮助。
  3. 堆转储分析:jmap 还提供了 -dump 选项,允许您在运行时生成堆转储快照。这对于在应用程序发生严重问题(如内存溢出)时进行故障排除或分析崩溃状态非常有用。 需要注意的是,jmap
    命令需要与 Java 虚拟机(JVM)一起使用,并且只能在支持的平台上运行。它提供了一种方便的方式来获取 Java
    应用程序的内存快照,以便进行深入分析和故障排除。

2、jmap的命令大全

以下是常用的 jmap 命令选项列表:

  1. jmap -heap <pid>:显示 Java 进程的堆内存使用情况,包括堆大小、已使用大小、垃圾回收器信息等。
  2. jmap -histo <pid>:显示 Java 进程中各个类的实例数量和占用内存大小的统计信息。
  3. jmap -histo:live <pid>:显示 Java 进程中活跃对象(未被垃圾回收)的类的实例数量和占用内存大小的统计信息。
  4. jmap -dump:live,format=b,file=<filename> <pid>:生成 Java 进程的堆转储快照,并将其保存到指定的文件中。只包括活跃对象。
  5. jmap -dump:format=b,file=<filename> <pid>:生成 Java 进程的完整堆转储快照,并将其保存到指定的文件中。
  6. jmap -F -dump:format=b,file=<filename> <pid>:在 Java 进程无响应时,强制生成完整堆转储快照。
  7. jmap -J<flag>:向被监视的 JVM 注入 JVM 参数。
  8. jmap -finalizerinfo <pid>:显示 Java 进程中等待终结的对象信息。 这些命令选项的 <pid> 参数是指 Java 进程的进程ID,用于指定要操作的目标进程。请注意,部分命令选项可能需要在具有相应权限的用户或管理员模式下运行。 这只是
    jmap 命令的一些常见用法,还有其他更多选项可以通过运行 jmap -help 命令来查看完整的命令说明。

3、示例

当您使用 jmap -histo <pid> 命令时,可以获取 Java 进程中各个类的实例数量和占用内存大小的统计信息。下面是一个命令示例:

$ jmap -histo 12345

上述命令中的 <pid> 替换为您要监视的 Java 进程的进程ID。执行该命令后,jmap 将输出类似以下的结果:

 num     #instances         #bytes  class name
----------------------------------------------
   1:        12345        1234567  com.example.ClassA
   2:         5678         987654  com.example.ClassB
   3:          789           54321  com.example.ClassC
   ...    ...      ...        ...

输出结果中的各列含义如下:

  • num:类的编号,表示在堆中的顺序。
  • #instances:该类的实例数量。
  • #bytes:该类实例占用的总内存大小。
  • class name:类的全限定名。

通过这个输出,您可以了解 Java 进程中各个类的对象分布情况和内存占用情况,有助于发现可能存在的对象泄漏或异常内存使用情况。

三、jps

1、jps有什么用?

jps是Java虚拟机进程状态工具(Java Process Status),它用于列出当前系统中正在运行的Java进程。jps命令可以显示每个Java进程的进程ID(PID)和主类名称,帮助用户快速了解Java应用程序的运行情况。jps命令的主要用途包括:

  1. 列出Java进程:通过运行jps命令,可以列出当前系统中正在运行的所有Java进程的进程ID和主类名称。
  2. 监控Java进程:可以使用jps命令结合其他监控工具,如jstatjstackjconsole等,对Java进程进行监控、诊断和性能分析。
  3. 校验Java进程:通过检查Java进程的PID和主类名称,可以确保指定的Java进程正在正确运行,并且可以与其他进程进行交互。

总之,jps是一个简单而有用的命令行工具,用于列出Java进程的信息,方便用户进行Java应用程序的管理和监控。

2、jps命令以及示例

以下是一些常用的jps命令选项和示例:

  1. 列出正在运行的Java进程:

    jps
    
  2. 列出正在运行的Java进程及其主类名称:

    jps -l
    
  3. 列出正在运行的Java进程及其JVM参数:

    jps -m
    
  4. 列出正在运行的Java进程及其JVM参数、主类名称:

    jps -ml
    
  5. 列出正在运行的Java进程及其JVM参数、主类名称、传递给主类的参数:

    jps -mvl
    
  6. 以自定义格式列出Java进程信息(进程ID和主类名称):

    jps -F
    
  7. 以自定义格式列出Java进程信息(进程ID、主类名称和JVM参数):

    jps -Fm
    
  8. 以自定义格式列出Java进程信息(进程ID、主类名称、JVM参数和传递给主类的参数):

    jps -Fml
    

示例用法:

  • 显示正在运行的Java进程及其主类名称:

    jps -l
    

    输出示例:

    12345 MainClass1
    67890 MainClass2
    
  • 显示正在运行的Java进程及其JVM参数、主类名称:

    jps -ml
    

    输出示例:

     12345 -Djava.vm.options=...
     67890 -Djava.vm.options=... MainClass2
     ```
    
    
  • 以自定义格式显示Java进程信息(进程ID、主类名称、JVM参数和传递给主类的参数):

    jps -Fml
    

    输出示例:

    12345 MainClass1 -Djava.vm.options=... -Xmx512m
    67890 MainClass2 -Djava.vm.options=...
    

这些示例演示了jps命令在不同选项下列出Java进程信息的用法。您可以根据需求选择合适的选项来查看特定的Java进程信息。

四、jstat

1、jstat有什么用?

jstat是Java统计监视工具(Java Statistics Monitoring),它用于收集和显示与Java虚拟机(JVM)相关的各种运行时统计数据。通过jstat命令,您可以实时监测和分析Java应用程序的性能指标,从而对应用程序进行优化和故障排除。

jstat的主要用途包括:

  1. 监视Java堆内存使用情况:通过jstat -gc命令可以获取Java堆内存的使用情况,包括堆的容量、使用量、垃圾回收等信息。
  2. 监视类加载和卸载情况:使用jstat -class命令可以查看已加载和已卸载的类数量和大小,以及类加载器的使用情况。
  3. 监视垃圾回收情况:通过jstat -gc命令可以观察垃圾回收的执行次数、时间和垃圾回收器的工作状态,帮助分析和调整垃圾回收策略。
  4. 监视线程情况:使用jstat -t命令可以查看线程数、各种线程状态以及峰值线程数等信息,有助于发现线程问题和优化线程使用。
  5. 监视编译情况:通过jstat -compiler命令可以监视即时编译器的使用情况,包括编译任务数量、成功编译次数等。
  6. 监视类加载器情况:使用jstat -loader命令可以观察类加载器的使用情况,包括类加载器数量、类加载和卸载次数等。

总之,jstat是一个强大的工具,可用于实时监控和收集Java应用程序的运行时统计数据,帮助开发人员了解应用程序的性能状况,并进行性能调优和故障排除。

2、jstat命令以及示例

jstat命令用于收集和显示与Java虚拟机(JVM)相关的各种运行时统计数据。下面是一些常用的jstat命令及其示例用法:

  1. 监视堆内存使用情况:

    jstat -gc <pid> <interval> <count>
    

    示例:

    jstat -gc 12345 1000 10
    
  2. 监视新生代和老年代的大小、容量和使用情况:

    jstat -gcutil <pid> <interval> <count>
    

    示例:

    jstat -gcutil 12345 1000 10
    
  3. 监视类加载和卸载情况:

    jstat -class <pid> <interval> <count>
    

    示例:

    jstat -class 12345 1000 10
    
  4. 监视线程数、线程状态和峰值线程数:

    jstat -t <pid> <interval> <count>
    

    示例:

    jstat -t 12345 1000 10
    
  5. 监视编译器的编译任务数量和成功编译次数:

    jstat -compiler <pid> <interval> <count>
    

    示例:

    jstat -compiler 12345 1000 10
    
  6. 监视类加载器的数量、类加载和卸载次数:

    jstat -loader <pid> <interval> <count>
    

    示例:

    jstat -loader 12345 1000 10
    

这些示例中的参数含义如下:

  • <pid>:Java应用程序的进程ID。
  • <interval>:数据收集时间间隔(以毫秒为单位)。
  • <count>:要收集的数据点数量。

执行以上命令后,jstat会定期收集指定时间间隔内持续的运行时统计数据,并输出到控制台。您可以根据实际需求选择适当的jstat命令和参数来监视和分析Java应用程序的运行时性能指标。

五、jstack

1、jstack有什么用?

jstack是Java开发中的一个命令行工具,用于生成Java虚拟机(JVM)当前运行时的线程快照。它可以帮助开发人员识别和解决多线程相关的问题。通过运行jstack命令,可以获取JVM中所有线程的状态和堆栈信息。这对于分析死锁、线程阻塞、死循环等问题非常有用。以下是jstack主要的应用场景和用途:

  1. 分析死锁:jstack可以输出线程的堆栈信息,帮助识别当多个线程因为互相等待资源而无法继续执行的情况,即死锁。

  2. 监视线程:jstack`可以周期性地获取线程快照,并输出线程的状态、执行轨迹和调用堆栈等信息,帮助跟踪和监视应用程序中的线程活动。

  3. 分析性能问题:通过查看线程的状态和堆栈信息,可以了解线程的执行情况,找到可能存在的性能瓶颈或潜在的资源竞争问题。

  4. 定位线程阻塞jstack可以显示线程等待的资源和锁,帮助找出线程阻塞的原因,并进行相应的调优。

  5. 检测死循环:通过查看线程的堆栈信息,可以判断是否存在死循环,并定位导致死循环的代码位置。

总之,jstack是一个用于分析和调试多线程应用程序的工具,它提供了线程状态、堆栈信息等有价值的数据,帮助开发人员定位和解决与多线程相关的问题。

2、jstack命令及示例

jstack命令用于生成Java虚拟机(JVM)线程快照。以下是jstack命令的基本语法和示例:

语法:

jstack [ options ] <pid>

参数说明:

  • options:可选参数,用于指定jstack的功能和输出格式。常用的选项包括:
    • -l: 长格式输出,包括关联的锁信息。
    • -m: 输出额外的JVM内存相关信息。
  • pid:必选参数,指定目标Java进程的进程ID。

示例1:生成线程快照

jstack 12345

上述命令会生成进程ID为12345的Java进程的线程快照,并输出到控制台。

示例2:生成详细线程快照

jstack -l 12345

上述命令会生成进程ID为12345的Java进程的详细线程快照,并输出到控制台。其中,-l选项指定了长格式输出,包括关联的锁信息。

示例3:生成线程快照并输出到文件

jstack -m 12345 > thread_dump.txt

上述命令会生成进程ID为12345的Java进程的线程快照,并将输出保存到名为thread_dump.txt的文件中。其中,-m选项指定了输出额外的JVM内存相关信息。

通过这些示例,你可以使用jstack命令来生成Java进程的线程快照,并获取线程状态和堆栈信息,用于调试和分析多线程相关的问题。注意,需要将示例中的"12345"替换为目标Java进程的实际进程ID。

六、visualvm

1、visualvm有什么用?

JVisualVM 是一个用于监视、分析和调优 Java 虚拟机(JVM)应用程序的工具。下面是一些使用 JVisualVM 的基本步骤:

  1. 启动 JVisualVM: 在 JDK 安装目录的 bin 目录下,可以找到名为 jvisualvm 的可执行文件(Windows 系统为 jvisualvm.exe)。双击运行该文件来启动 JVisualVM 工具。

  2. 连接到目标应用程序``: JVisualVM 可以通过多种方式连接到目标应用程序,最常用的方式是在工具的左侧导航栏中选择 “本地” 或 “远程” 选项,然后在应用程序列表中选中你想要连接的应用程序,点击 “连接” 按钮进行连接。

  3. 监视和分析应用程序: 连接成功后,JVisualVM 将显示目标应用程序的概览页面,其中包含了应用程序的概要信息。你可以使用工具栏上的不同选项卡来查看各种监视数据,如内存、线程、GC、CPU
    等。你还可以生成堆栈跟踪、线程转储和剖析结果,以帮助分析和解决性能问题。

  4. 进行性能调优: JVisualVM 提供了一些用于性能调优的工具。例如,可以使用内存分析器来查找内存泄漏和优化内存使用。可以使用剖析器来识别应用程序中的热点,找到性能瓶颈并进行优化。

此外,JVisualVM 还支持插件扩展,你可以安装和启用各种插件来增强其功能和可定制性。
请注意,要使用 JVisualVM,目标应用程序必须在运行时启用 JMX(Java Management Extensions)功能。如果你想远程监视一个应用程序,还需要确保目标主机上的防火墙和网络设置允许 JMX 连接。

七、总结

下面是对一些常用的JVM相关工具和命令的总结:

  1. jstat(Java Virtual Machine Statistics Monitoring Tool):用于监控和测量Java虚拟机的各种统计信息,如垃圾回收、类装载、内存、线程等。可以使用jstat命令来获取这些信息,并可以以文本或CSV格式输出。

  2. jstack(Java Stack Trace):用于生成Java虚拟机当前运行时的线程快照。通过jstack命令,可以获取线程的状态和堆栈信息,帮助分析死锁、线程阻塞等问题。

  3. jmap(Java Memory Map):用于生成Java虚拟机的内存转储快照。可以使用jmap命令来获取堆内存使用情况、类统计信息、内存分配情况等。还可以生成堆转储文件,供后续分析使用。

  4. jps(Java Virtual Machine Process Status Tool):用于列出当前运行的Java进程。jps命令可以输出Java进程的进程ID和主类名,方便在命令行中查看Java进程的状态。

  5. VisualVM:是一个功能强大的Java虚拟机监视和分析工具。它可以通过插件支持各种功能,如垃圾回收监控、线程分析、内存分析、性能剖析等。VisualVM提供了直观的图形界面,方便进行实时监控和分析。

这些工具和命令在JVM性能调优、故障排查和内存分析中非常有用。开发人员可以根据具体的需求选择适合的工具来监控和分析Java应用程序,以优化性能并解决潜在的问题。