【Java可执行命令】(十六)诊断命令请求发送工具 jcmd:提供一种简单而强大的方式来管理和监控 Java 进程 ~

Java可执行命令之jcmd

  • [1️⃣ 概念](#1️⃣ 概念)
  • [2️⃣ 优势和缺点](#2️⃣ 优势和缺点)
  • [3️⃣ 使用](#3️⃣ 使用)
      • [3.1 语法格式](#3.1 语法格式)
      • [3.2 jcmd -l:列出正在运行的 Java 进程](#3.2 jcmd -l:列出正在运行的 Java 进程)
      • [3.3 jcmd < pid> help:列出特定进程的诊断命令列表](#3.3 jcmd < pid> help:列出特定进程的诊断命令列表)
      • [3.4 jcmd < pid> < command>:执行诊断命令](#3.4 jcmd < pid> < command>:执行诊断命令)
  • [4️⃣ 应用场景](#4️⃣ 应用场景)
  • [🌾 总结](#🌾 总结)

1️⃣ 概念

jcmd 是 Java 中用于与正在运行的 Java 进程进行交互的命令行工具。它旨在提供一种简单而强大的方式来管理和监控 Java 进程,以满足开发、调试和性能优化等需求。

jcmd 的核心概念是通过命令行发送指令给正在运行的 Java 进程,这些指令称为诊断命令(Diagnostic Command)。诊断命令可以执行各种操作,例如生成线程转储、查看堆内存使用情况、触发 GC、打印系统属性等。

jcmd 的实现原理涉及与 Java 进程的通信机制。具体来说,它利用了 Java 中的诊断功能(Diagnostic API),这个API提供了一组用于监控和管理 Java 进程的接口。通过 jcmd 命令发送到某个 Java 进程的指令会被转发给该进程的诊断代理,然后由代理执行相应的诊断命令。

2️⃣ 优势和缺点

优点:

  • 方便管理:通过 jcmd 命令,可以在不停止进程的情况下对 Java 应用程序进行管理和监控;
  • 强大功能:提供了丰富的诊断命令,可以获取详细的应用程序信息、捕获堆转储、动态修改虚拟机参数等;
  • 简单易用:通过命令行的方式,使用相对简单,不需要额外的代码修改或依赖库。

缺点:

  • 需要访问权限:使用 jcmd 进行诊断和控制某个 Java 进程需要适当的访问权限;
  • 不支持远程应用程序:仅支持与本地 Java 进程进行交互,不支持与远程应用程序通信。

3️⃣ 使用

3.1 语法格式

jcmd 命令的使用语法如下:

bash 复制代码
jcmd <pid|main class> <command> [<command arguments>]

其中,<pid|main class> 可以指定要操作的 Java 进程ID或主类名。 <command> 是预定义的诊断命令名称,而 <command arguments> 则是可选的参数。

要注意的是,命令必须是所选 jvm 的有效 jcmd命令。可以使用命令"help"查看哪些命令可用。

如果指定 pid 为0,则将向所有Java进程发送命令。

主类参数将用于匹配(部分或完全)用于启动Java的类。如果没有给出任何选项,则列出Java进程(与-p相同)。

总的来说,jcmd 命令有以下常见的用法:

  • jcmd -l:列出正在运行的 Java 进程;
  • jcmd <pid> help:列出特定进程的诊断命令列表;
  • jcmd <pid> <command>:执行诊断命令;
  • jcmd <pid> GC.heap_info:查看堆内存使用情况;
  • jcmd <pid> GC.run:触发GC;
  • jcmd <pid> Thread.print:打印线程堆栈跟踪。

下面我们逐一详细介绍。

而同时需要注意的是,使用 jcmd 进行诊断和控制某个 Java 进程需要适当的访问权限。如果无法访问指定进程,则可能需要使用管理员权限或其他特权用户进行操作。

并且由于 jcmd 允许对运行中的 Java 进程执行敏感操作,因此在部署和使用 jcmd 时需谨慎,确保只有受信任的用户能够访问。

3.2 jcmd -l:列出正在运行的 Java 进程

jcmd -l 是一个用于列出正在运行的 Java 进程的命令。使用 jcmd -l 命令时,它会扫描当前系统中的所有 Java 进程,并返回每个进程的进程 ID(PID)和启动类的主类名。这对于确定正在运行的 Java 进程及其相关信息非常有用。

例如,下面是 jcmd -l 的示例输出:

1234 com.example.Main
5678 org.myapp.Application

上述输出表示有两个 Java 进程正在运行:进程 ID 为 1234 的进程在使用 com.example.Main 类作为入口点,进程 ID 为 5678 的进程在使用 org.myapp.Application 类作为入口点。

jcmd -l 不提供任何关于进程的详细信息,它只给出了进程的基本信息。如果需要更多有关特定 Java 进程的信息,可以使用其他命令,如 jcmd <pid> VM.flagsjcmd <pid> Thread.print

3.3 jcmd < pid> help:列出特定进程的诊断命令列表

jcmd <pid> help 是一个用于列出特定进程的诊断命令列表的命令。当我们知道某个 Java 进程的进程 ID(PID)时,可以使用 jcmd <pid> help 命令来获取该进程所支持的所有诊断命令的列表。

例如,假设我们要获取进程 ID 为 118472 的 Java 进程的诊断命令列表,我们可以运行以下命令:

jcmd 118472 help

执行该命令后,会返回类似下面的输出:

118472:
The following commands are available:
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
VM.check_commercial_features
VM.unlock_commercial_features
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
VM.classloader_stats
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.finalizer_info
GC.heap_info
GC.run_finalization
GC.run
VM.uptime
VM.dynlibs
VM.flags
VM.system_properties
VM.command_line
VM.version

上述输出表示进程 ID 为 118472 的 Java 进程支持的一些诊断命令列表。可以从中选择特定的命令来查看和调试该进程的不同方面,如打印线程信息、监视内存使用情况等。

注意,可用的诊断命令列表取决于安装的 JDK 版本和 JVM 配置。因此,不同的 Java 版本可能会提供不同的命令集。

以下列出一些常见的 Java 诊断命令以及它们的作用。这些命令可以帮助进行 JVM 监控、故障排除和性能分析等工作。注意,不同的命令可能需要不同的参数和选项来完成更具体的任务。

命令 作用
JFR.stop 停止 Java Flight Recorder(JFR)事件录制
JFR.start 开始 Java Flight Recorder(JFR)事件录制
JFR.dump 将已录制的 JFR 事件转储到文件中
JFR.check 检查当前 JFR 事件录制的状态和设置
VM.native_memory 显示某个 Java 进程的本地内存使用情况
VM.check_commercial_features 检查是否启用了商业特性
VM.unlock_commercial_features 解锁并完全启用已启用的商业特性
ManagementAgent.stop 停止 Java 管理代理
ManagementAgent.start_local 启动一个本地连接的 Java 管理代理
ManagementAgent.start 启动一个远程连接的 Java 管理代理
VM.classloader_stats 输出关于类加载器统计信息的摘要
GC.rotate_log 手动旋转 GC 日志文件
Thread.print 打印当前 Java 进程中的线程堆栈信息
GC.class_stats 显示在堆中加载和卸载类的统计信息
GC.class_histogram 显示在堆上存在的对象数目,按类进行分类
GC.heap_dump 导出当前堆的快照为一个 HPROF 文件
GC.finalizer_info 显示等待终结器队列中对象的信息
GC.heap_info 显示当前堆的概要信息
GC.run_finalization 运行所有已注册但尚未运行的 finalize() 方法
GC.run 强制进行一次垃圾回收
VM.uptime 显示 JVM 的总运行时间
VM.dynlibs 列出当前虚拟机加载的动态链接库信息
VM.flags 显示正在使用的 JVM 标志参数
VM.system_properties 显示 Java 系统属性
VM.command_line 显示 Java 虚拟机的启动命令行参数
VM.version 显示正在使用的 Java 虚拟机版本信息

大家也可以参考相应的文档或使用命令的帮助选项来获取更多详细信息。

3.4 jcmd < pid> < command>:执行诊断命令

jcmd <pid> <command> 是一个用于执行特定进程的诊断命令的命令。

当我们知道某个 Java 进程的进程 ID(PID)以及要执行的诊断命令时,可以使用 jcmd <pid> <command> 命令来执行该进程的诊断命令。

例如,假设我们要执行进程 ID 为 1234 的 Java 进程的命令 GC.class_stats,我们可以运行以下命令:

jcmd 1234 GC.class_stats

执行该命令后,它会向该进程发送相应的命令,并获取并显示与 GC.class_stats 相关的统计信息。

不同的诊断命令可能会有不同的输出或操作。可以根据需求选择适当的命令以及其他可能需要的参数和选项。注意,要成功执行诊断命令,确保拥有足够的权限来操作目标进程。

4️⃣ 应用场景

  • 分析和调试:用于获取运行中 Java 进程的信息、线程状态和堆转储等,以进行并发分析和代码调试;
  • 性能监控和优化:观察堆内存使用情况、GC活动、CPU消耗等指标,从而帮助进行性能调优和排查性能问题;
  • 运维和监控:与其他工具或脚本集成,用于自动化管理和监控 Java 进程,以实现自动化运维和健壮的监控系统。

🌾 总结

jcmd 是一个强大且方便的命令行工具,用于与正在运行的 Java 进程进行交互、管理和监控。通过它,可以执行各种诊断命令以了解应用程序的状态,进行调试和性能优化,并提供简洁易用的命令行界面。然而,在使用 jcmd 时需要注意安全性问题,并且目前仅支持本地 Java 进程的操作。无论是开发人员还是运维人员,都可以从 jcmd 中获益,并提高对 Java 应用程序的管理和监控能力。

相关推荐
罗曼蒂克在消亡2 分钟前
2.3MyBatis——插件机制
java·mybatis·源码学习
Fairy_sevenseven7 分钟前
【二十八】【QT开发应用】模拟WPS Tab
开发语言·qt·wps
_GR14 分钟前
每日OJ题_牛客_牛牛冲钻五_模拟_C++_Java
java·数据结构·c++·算法·动态规划
蜡笔小新星15 分钟前
Python Kivy库学习路线
开发语言·网络·经验分享·python·学习
凯子坚持 c15 分钟前
C语言复习概要(三)
c语言·开发语言
coderWangbuer23 分钟前
基于springboot的高校招生系统(含源码+sql+视频导入教程+文档+PPT)
spring boot·后端·sql
无限大.27 分钟前
c语言200例 067
java·c语言·开发语言
余炜yw29 分钟前
【Java序列化器】Java 中常用序列化器的探索与实践
java·开发语言
攸攸太上29 分钟前
JMeter学习
java·后端·学习·jmeter·微服务
篝火悟者30 分钟前
问题-python-运行报错-SyntaxError: Non-UTF-8 code starting with ‘\xd5‘ in file 汉字编码问题
开发语言·python