jcmd: JDK14中调试神器的用法

  介绍

这篇文章主要讲解了jcmd: JDK14中调试神器的用法,内容清晰明了,对此有兴趣的小伙伴可以学习一下,相信大家阅读完之后会有帮助。

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

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

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

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

jcmd的语法比较简单:

 jcmd [pid |主类)命令…| PerfCounter。打印| - f文件名
  
  jcmd (- l)
  
  jcmd - h 

pid和主类是二选一:

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

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

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

。/jcmd 93989帮助   93989:   可用以下命令:   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   

Perfcounter帮助。打印表示要打印java进程暴露的性能计数器。

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

- l列出不是运行在码头工人JVM中。

- h表示帮助。

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

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

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

使用JCmd pid线程。打印- l可以打印出java程序的堆栈信息。其中- l表示输出java.util。并发的锁信息。

下面看个简单的例子:

。/jcmd 93989线程。打印- l      完整的Java线程转储热点(TM) 64位服务器虚拟机(14.0.1 + 7混合模式,分享):      鼻中隔黏膜下切除术后线程类信息:   _java_thread_list=0 x00007fbeb1c4cb10长度=12,元素={   0 x00007fbeb282a800, 0 x00007fbeb282d800 0 x00007fbeb282e800 0 x00007fbeb2830800,   0 x00007fbeb2831800, 0 x00007fbeb2832000 0 x00007fbeb2833000 0 x00007fbeb3831000,   0 x00007fbeb3822000, 0 x00007fbeb3174000 0 x00007fbeb3815000 0 x00007fbeb226f800   }      “引用Handler"# 2守护进程一家=10 os_prio=31 cpu=0.64 ms运行=8996.59年代tid=0=0 x4703 x00007fbeb282a800国家免疫日等待>。/jcmd 93989 GC.heap_info   93989:   garbage first堆总71680 k, 34410 k [0 x00000007d4400000, 0 x0000000800000000)   区域大小1024 k,幸存者20年轻(20480 k), 4 (4096 k)   Metaspace使用23810 k,预留容量24246 k, 24752 k, 1071104 k   类空间使用2850 k,容量3015 k, 3072 k,保留1048576 k

打印堆转储

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

。/jcmd 93989 GC。heap_dump heap_dump.out   93989:   倾销heap_dump堆。出……   堆转储文件创建(27727979字节在0.643秒)

堆转储需要传入一个文件名,存放倾倒出来的信息。

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

。/jcmd 93989 GC.class_histogram      93989:   num # #字节实例类名(模块)   -------------------------------------------------------   1:25826 11748304 (B (java.base@14.0.1)   2:2233 1971800 (I (java.base@14.0.1)   3:5154 614928 . lang。类(java.base@14.0.1)   4:24757 594168 . lang。字符串(java.base@14.0.1)   5:4491 439432 [Ljava.lang.Object;(java.base@14.0.1)   6:13177 421664 java . util . concurrent。ConcurrentHashMap美元节点(java.base@14.0.1)   7:5025 160800 java.util。美元HashMap节点(java.base@14.0.1)   8:8793 140688 . lang。对象(java.base@14.0.1)   9:212 103584(美元Ljava.util.concurrent.ConcurrentHashMap节点;(java.base@14.0.1)

jcmd: JDK14中调试神器的用法