Jcmd:一个可以全部统治的Jdk命令行工具

Jcmd: One Jdk Command-Line Tool to Rule Them All

我在过去的几篇文章中都引用了方便的JDK工具jcmd,但是像我以前对jps所做的那样,仅专注于其实用性。 jcmd工具是随Oracle Java 7引入的,在通过使用Java标识Java进程的ID(类似于jps),获取堆转储(类似于jmap),获取线程转储(类似于jstack)来解决JVM应用程序问题时特别有用。 ),查看虚拟机特征,例如系统属性和命令行标志(类似于jinfo),以及获取垃圾回收统计信息(类似于jstat)。 jcmd工具被称为"用于调查和解决JVM应用程序问题的瑞士军刀"和"隐藏的宝石"。

使用大多数JDK命令行工具(包括jcmd)时,标识要使用命令行工具的Java进程的进程ID(pid)通常很重要。 只需使用不带任何参数的命令运行jcmd即可轻松完成此操作,如下一个屏幕快照所示。

在上面的示例中,不带参数运行jcmd表示两个Java进程正在运行(jcmd自身的pid为324,另一个Java进程的pid为7268)。 请注意,尽管在列出Java进程时jcmd的工作方式与jps非常相似,但是与jps相比,jcmd列出了更多信息,而没有参数-lm

运行jcmd -h将显示jcmd的帮助和使用信息,如下面的屏幕快照所示。

如刚刚所示,该帮助说明jcmd在"未给出选项"的情况下"列出Java进程"。 该帮助还指出,这与运行jcmd -p类似,但是我认为这意味着说不带选项运行jcmd等同于运行jcmd -l,这在下一个屏幕快照中显示。

与在不带任何选项的情况下运行jcmd时一样,jcmd -l列出了Java进程及其各自的pid。 本例中的pids不同,因为它是jcmd的不同执行方式,并且这次我运行的Java进程也不同。

运行jcmd -h显示相对较少的选项。 为了查看jcmd支持的许多功能的帮助,需要询问jcmd特定Java进程支持哪些功能。 下一个屏幕快照对此进行了说明。 我首先运行不带选项的jcmd来发现感兴趣的Java进程的pid(在本例中为6320)。 然后,我可以运行jcmd 6320 help来查看jcmd支持的命令。

上一个屏幕快照演示了jcmd支持pid标识的特定Java VM的命令。 具体来说,它指出"以下命令可用:",然后列出它们:

  • JFR停止

  • 启动JFR

  • JFR转储

  • JFR。检查

  • VM.native_memory

  • VM.check_commercial_features

  • VM.unlock_commercial_features

  • 管理代理停止

  • ManagementAgent.start_local

  • ManagementAgent.start

  • GC.rotate_log

  • GC.class_stats

  • GC.class_histogram

  • GC.heap_dump

  • GC.run_finalization

  • GC运行

  • 线程打印

  • 虚拟机正常运行时间

  • 虚拟机标志

  • VM.system_properties

  • VM.command_line

  • 虚拟机版本

  • 帮帮我

  • 当针对其他Java VM进程的pid运行jcmd <pid> help时,可能会获得不同的可用命令列表。 在针对pid为1216的进程执行jcmd 1216 help的下一个屏幕快照中对此进行了说明。

    通过比较最后两个屏幕快照,可以清楚地看到jcmd支持针对不同Java VM实例的不同命令。 这就是为什么通过在help命令中指定pid列出特定VM支持的命令的原因。 针对第二个VM可用的一些命令(在本例中为pid 1216)未针对最初检查的VM列出,其中包括以下命令:

  • VM.log

  • 管理代理状态

  • Compiler.directives_clear

  • Compiler.directives_remove

  • Compiler.directives_add

  • Compiler.directives_print

  • VM.print_touched_methods

  • 编译器

  • 编译器代码清单

  • 编译器队列

  • VM.classloader_stats

  • JVMTI.data_dump

  • VM.stringtable

  • 虚拟机

  • VM.class_hierarchy

  • GC.finalizer_info

  • GC.heap_info

  • VM.info

  • VM.dynlibs

  • VM.set_flag

  • 该"帮助"还建议:"有关特定命令的更多信息,请使用'help '。" 下一个屏幕快照专门针对jcmdThread.print说明了如何执行此操作

    jcmd Thread.print命令的主题上,是时候说明使用它来查看Java进程的线程堆栈的好时机。 下一个屏幕快照显示了执行jcmd <pid> Thread.print时看到的结果冗长得多的开始(在本例中,对于使用pid 6320的Java进程)。

    jcmd支持几种VM.*命令:VM.versionVM.uptimeVM.command_lineVM.flagsVM.system_propertiesVM.native_memoryVM.classloader_stats。 下一个屏幕快照说明了jcmd <pid> VM.versionjcmd <pid> VM.uptime在pid 6320的Java进程中的用法。

    下一个屏幕快照展示了对使用进程6320的进程执行jcmd <pid> VM.command_line的过程。

    从该屏幕快照(其中显示了运行jcmd 6320 VM.command_line的输出的顶部)中,我们可以从提供给该进程的JVM命令行参数中看到它是与NetBeans相关的进程。 使用pid 6320对Java进程运行命令jcmd <pid> VM.flags会显示传递给该进程的HotSpot选项。

    可以使用jcmd <pid> VM.system_properties列出Java进程使用的系统属性,下一个屏幕快照对此进行了说明。

    当尝试对尚未启用本机内存跟踪(NMT)的Java进程运行jcmd <pid> VM.native_memory时,将显示错误消息"未启用本机内存跟踪",如下一个屏幕快照所示。

    要使用命令jcmd <pid> VM.native_memory,应使用-XX:NativeMemoryTracking=summary-XX:NativeMemoryTracking=detail选项启动要测量的JVM(java进程)。 使用这些选项之一启动VM后,就可以对该JVM进程执行命令jcmd <pid> VM.native_memory baseline然后是jcmd <pid> VM.native_memory detail.diff

    命令jcmd <pid> VM.classloader_stats提供对类加载器的了解。 下一个针对pid 1216的Java进程的屏幕快照中显示了该快照:

    jcmd <pid> VM.class_hierarchy是一个有趣的命令,可显示在目标Java VM进程中加载的类的层次结构。

    jcmd <pid> VM.dynlibs可用于查看动态库信息。 在针对使用pid 1216的Java进程执行时的下一个屏幕快照中对此进行了演示。

    jcmd <pid> VM.info列出了大量有关目标Java VM进程的信息,包括VM摘要以及有关进程,垃圾回收事件,动态库,提供给VM的参数以及主机的某些特征的信息。 在下一个jcmd 1216 VM.info的屏幕快照中演示了此输出开始的一小部分:

    下一个屏幕快照演示jcmd <pid> VM.stringtablejcmd <pid> VM.symboltable的用法:

    下一个屏幕快照演示了jcmd <pid> Compiler.directives_print的使用。

    jcmd支持的几个命令支持管理和监视垃圾收集。 其中两个是jcmd <pid> GC.run [类似于System.gc()]和jcmd <pid> GC.run_finalization [类似于System.runFinalization()]。 在下一个屏幕快照中将演示其中的两个。

    命令jcmd <pid> GC.class_histogram提供了一种方便的方式来查看对象直方图,如下一个屏幕快照所示。

    jcmd可用于使用jcmd <pid> GC.heap_dump <filename>针对正在运行的Java VM生成堆转储,这将在下一个屏幕快照中进行演示。

    现在,可以使用jhat命令来处理jcmd生成的堆转储,如以下两个屏幕快照所示。

    有些jcmd命令仅适用于使用-XX:+UnlockDiagnosticVMOptions JVM标志启动的Java VM。 下一个屏幕快照演示了当我尝试对未使用标志-XX:+UnlockDiagnosticVMOptions启动的Java VM运行jcmd <pid> GC.class_stats时发生的情况。

    使用-XX:+UnlockDiagnosticVMOptions启动目标VM时,jcmd <pid> GC.class_stats显示"有关Java类元数据的统计信息"。

    这篇文章介绍了jcmd提供的一些命令,但没有涉及与Java Flight Recorder [JFR]相关的功能(名称以JFR.*开头的命令),以检查和启用商业功能(jcmd <pid> VM.check_commercial_featuresjcmd <pid> VM.unlock_commercial_features)。

    在一个命令行工具中,jcmd汇集了几个命令行JDK工具的功能。 这篇文章演示了jcmd提供的一些功能。