简介

jcmd是JDK自带的调试工具,具有非常强大的功能。jcmd是JDK7中正式引入的,有了jcmd,完全可以替换很多常用的其他工具,比如jstak和jmap。

jcmd可以将具体的诊断命令发送给JVM。为了安全起见,使用jcmd的用户必须跟运行的java程序具有同样的用户和用户组。

jcmd的调试命令有很多种,每一种调试命令又有自己的参数。

本文将会结合具体的例子详细讲解jcmd的使用。

jcmd的语法

jcmd的语法比较简单:

jcmd [pid | main-class] command... | PerfCounter.print | -f filename

jcmd [-l]

jcmd -h

pid和main-class是二选一:

其中pid表示要发送诊断命令的java进程id。

也可以指定main-class,表示要发送诊断命令给运行该main-class的java进程。

command表示可以在jcmd中运行的命令,我们看下jcmd支持哪些命令:

./jcmd 93989 help
93989:
The following commands are available:
Compiler.CodeHeap_Analytics
Compiler.codecache
Compiler.codelist
Compiler.directives_add
Compiler.directives_clear
Compiler.directives_print
Compiler.directives_remove
Compiler.queue
GC.class_histogram
GC.class_stats
GC.finalizer_info
GC.heap_dump
GC.heap_info
GC.run
GC.run_finalization
JFR.check
JFR.configure
JFR.dump
JFR.start
JFR.stop
JVMTI.agent_load
JVMTI.data_dump
ManagementAgent.start
ManagementAgent.start_local
ManagementAgent.status
ManagementAgent.stop
Thread.print
VM.class_hierarchy
VM.classloader_stats
VM.classloaders
VM.command_line
VM.dynlibs
VM.events
VM.flags
VM.info
VM.log
VM.metaspace
VM.native_memory
VM.print_touched_methods
VM.set_flag
VM.stringtable
VM.symboltable
VM.system_properties
VM.systemdictionary
VM.uptime
VM.version
help

Perfcounter.print表示要打印java进程暴露的performance counters。

-f filename表示从文本文件中读取要运行的命令。

-l 列出不是运行在docker中JVM。

-h 表示帮助。

下面我们举几个常用的例子

列出运行的JVM

./jcmd -l
98109 jdk.jcmd/sun.tools.jcmd.JCmd -l

通过使用jcmd -l可以列出所有正在运行的JVM进程。跟jps是一样的。

打印stack信息

使用jcmd pid Thread.print -l可以打印出java程序的stack信息。其中-l表示输出java.util.concurrent的lock信息。

下面看个简单的例子:


./jcmd 93989 Thread.print -l Full thread dump Java HotSpot(TM) 64-Bit Server VM (14.0.1+7 mixed mode, sharing): Threads class SMR info:
_java_thread_list=0x00007fbeb1c4cb10, length=12, elements={
0x00007fbeb282a800, 0x00007fbeb282d800, 0x00007fbeb282e800, 0x00007fbeb2830800,
0x00007fbeb2831800, 0x00007fbeb2832000, 0x00007fbeb2833000, 0x00007fbeb3831000,
0x00007fbeb3822000, 0x00007fbeb3174000, 0x00007fbeb3815000, 0x00007fbeb226f800
} "Reference Handler" #2 daemon prio=10 os_prio=31 cpu=0.64ms elapsed=8996.59s tid=0x00007fbeb282a800 nid=0x4703 waiting on condition [0x000070000440d000]
java.lang.Thread.State: RUNNABLE
at java.lang.ref.Reference.waitForReferencePendingList(java.base@14.0.1/Native Method)
at java.lang.ref.Reference.processPendingReferences(java.base@14.0.1/Reference.java:241)
at java.lang.ref.Reference$ReferenceHandler.run(java.base@14.0.1/Reference.java:213) Locked ownable synchronizers:
- None

打印heap info

使用jcmd pid GC.heap_info可以获得heap info。

./jcmd 93989 GC.heap_info
93989:
garbage-first heap total 71680K, used 34410K [0x00000007d4400000, 0x0000000800000000)
region size 1024K, 20 young (20480K), 4 survivors (4096K)
Metaspace used 23810K, capacity 24246K, committed 24752K, reserved 1071104K
class space used 2850K, capacity 3015K, committed 3072K, reserved 1048576K

打印heap dump

如果想知道heap里面到底有什么,则可以通过下面的命令将heap dump出来:

./jcmd 93989 GC.heap_dump heap_dump.out
93989:
Dumping heap to heap_dump.out ...
Heap dump file created [27727979 bytes in 0.643 secs]

heap dump需要传入一个文件名,存放dump出来的信息。

统计heap使用情况

有时候我们需要统计一下heap中各个对象的使用情况,则可以下面方法:

./jcmd 93989 GC.class_histogram

93989:
num #instances #bytes class name (module)
-------------------------------------------------------
1: 25826 11748304 [B (java.base@14.0.1)
2: 2233 1971800 [I (java.base@14.0.1)
3: 5154 614928 java.lang.Class (java.base@14.0.1)
4: 24757 594168 java.lang.String (java.base@14.0.1)
5: 4491 439432 [Ljava.lang.Object; (java.base@14.0.1)
6: 13177 421664 java.util.concurrent.ConcurrentHashMap$Node (java.base@14.0.1)
7: 5025 160800 java.util.HashMap$Node (java.base@14.0.1)
8: 8793 140688 java.lang.Object (java.base@14.0.1)
9: 212 103584 [Ljava.util.concurrent.ConcurrentHashMap$Node; (java.base@14.0.1)

上面的结果非常有用,在一些性能调试方法可以起到意想不到的作用。

JFR功能

jcmd还支持jfr功能。JFR的全称叫做Java Flight Recorder。你可以将其看做是JVM中一些事件的记录器。

有关JFR的更多内容,将会在我的下一篇文章中详细讲解。

总结

jcmd还有很多其他的功能,大家可以多用多探索。

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/jdk14-jcmd/

本文来源:flydean的博客

欢迎关注我的公众号:程序那些事,更多精彩等着您!

jcmd:JDK14中的调试神器的更多相关文章

  1. 【转】段错误调试神器 - Core Dump详解

    from:http://www.embeddedlinux.org.cn/html/jishuzixun/201307/08-2594.html 段错误调试神器 - Core Dump详解 来源:互联 ...

  2. Eruda 一个被人遗忘的调试神器

    Eruda 一个被人遗忘的调试神器 引言   日常工作中再牛逼的大佬都不敢说自己的代码是完全没有问题的,既然有问题,那就也就有调试,说到调试工具,大家可能对于 fiddler.Charles.chro ...

  3. ios webapp调试神器MIHTool

    android平台有直接用chrome beta就可以调试,具体操作办法可以查看这篇教程<Android 设备 Chrome 远程调试>Mac的高富帅直接可以用safari提供“web检查 ...

  4. eruda手机端调试神器

    在日常的移动端开发时,一般都是试用chrome浏览器的移动端模式进行开发和调试,如果想在手机上能和浏览器一样看控制台调试就更加完美了: 一个手机端调试神器eruda是一个专为手机网页前端设计的调试面板 ...

  5. 移动端调试神器vconsole,手机端网页的调试工具Eruda

    移动端调试神器vconsole,手机端网页的调试工具Eruda 移动端中使用 vConsole调试 移动端调试工具vconsole安装Git地址:https://github.com/WechatFE ...

  6. vue 代码调试神器

    一.序 工欲善其事,必先利其器.作为一名资深程序员,相信必有一款调试神器相伴左右,帮助你快速发现问题,解决问题.作为前端开发,我还很年轻,也喜欢去捣鼓一些东西,借着文章的标题,先提一个问题:大家目前是 ...

  7. GDB中汇编调试

    GDB中汇编调试 1.输入代码 2.使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,时遇到问题使用-m32指令报错,参考卢肖明同学博客知道这是 ...

  8. 在VS 2015中边调试边分析性能

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 对代码进行性能分析,之前往往是一种独立的Profiling过程,现在在VS 2015中可以结 ...

  9. [安卓][转]Android eclipse中程序调试

    一:断点调试 用eclipse开发android程序的时,跟VS一样是可以断点单步调试的.步骤如下.1 设置断点:在编码窗体的左边框上用鼠标双击,或者右键点击菜单,选择 Toggle Breakpoi ...

  10. Android eclipse中程序调试

    一:断点调试 用eclipse开发android程序的时,跟VS一样是可以断点单步调试的.步骤如下.1 设置断点:在编码窗体的左边框上用鼠标双击,或者右键点击菜单,选择 Toggle Breakpoi ...

随机推荐

  1. 第128篇:浏览器存储(cookie、webStorage、 IndexedDB)

    好家伙,本篇为<JS高级程序设计>第二五章"浏览器存储"学习笔记 我们先来讲个故事 一个"薅羊毛"的故事 (qq.com) 概括一下,就是 有个人通 ...

  2. mysql-批量修改表的主键id,修改成联合主键

    1.sql脚本 一. 通过sql脚本,查出所有表的功能,并编写插入修改的联合主键,sql select concat('ALTER table ', TABLE_NAME, ' DROP PRIMAR ...

  3. Java 小练习(3) 方法的修改+ 调用

    1 package com.bytezero.exer; 2 3 public class ExerTest 4 { 5 public static void main(String[] args) ...

  4. VC-MFC(2) 随笔笔记

    1 //点击按钮出来对话框---------------- 2 3 1.首先添加 对话框(标识符) 4 2.在点击按钮出来第二个对话框,直接鼠标右键 新建 类 5 3.在.CPP添加新建类的 头文件 ...

  5. PetriCrode ---Code Genreation for Colored Petri Nets Annotated with Pragmatics

    1. PetriCode lets users generate code from CPN  models annotated with pragmatics ,PetriCode allows t ...

  6. liunx 大文件切割,catalina.out 大文件打开

    工作中,由于没有没有配日志文件切割,不小心日志文件上G了,用tail -f   或 cat 命令都难打开了,但偏这时候出了点事,需要查日志 怎么呢.第一条件命令    tail -50000f  ca ...

  7. Apollo获取配置异常:Load config failed, will retry in 1 SECONDS

    一.现象 apollo开启秘钥,服务获取配置参数需要启动参数中添加:jvm参数-Dapollo.accesskey.secret=XXX.日志如下: 二.解决方案 应用服务器时间异常,重置应用服务器时 ...

  8. iptables五表五链及对应实例

    iptables是Linux系统上用于配置网络包过滤规则的工具,它使用表(tables)和链(chains)来组织规则.以下是iptables中的五表五链及其对应的实例说明: 五表 filter表:默 ...

  9. STM32 USB协议和代码分析

    一 前言: usb接口是一个非常重要的通信接口,它的协议是有些复杂的.作为一个工程师,对usb协议和代码进行分析,是一个必备的素质和技能.最近一个项目用到了USB存储接口,花了不少时间把项目做完之后, ...

  10. vue入门教程之-插槽

    vue入门教程之-插槽 欢迎关注博主公众号「java大师」, 专注于分享Java领域干货文章, 关注回复「资源」, 免费领取全网最热的Java架构师学习PDF, 转载请注明出处 https://www ...