jdk常用的七种性能监控命令行工具

引言

在jdk的开发包里,除了我们常用的java.exejavac.exe程序外,还有一系列辅助工具,这些工具可以帮助我们更好地分析指定java程序的运行状态,比如jstack.exejps.exejstate.exe等。下面我们对一些重要的工具进行讲解。

注意:在jdk8及以前,工具类的可执行文件的实现都在lib/tools.jar上,但是在jdk9及以后,以前存储在lib中的lib/rt.jarlib/tools.jarlib.dt.jar,以及其他各种内部jar文件现在以更高效的格式存储在lib目录中特定的实现文件中。

注意:我使用的环境为Windows10,jdk11。此处放出jdk11工具程序的官方说明文档,读者可以从此文档中获取详细信息。

进程查看器——jps

jps命令会列出运行在本地的所有java进程。

它的相关参数如下:

  • -q:指定jps只输出进程ID,而不输出类的名称。
  • -m:输出传递给java进程的参数。
  • -l:输出主函数的完整路径。
  • -v:显示传递给java虚拟机的参数。

示例如下:

C:\Users\hu'nan>jps -m -l -v
19536 cn.bigkai.ApplicationStart -Xlog:gc=trace:file=gc.log -Xmx32M -Xms32M -javaagent:F:\instrument\java\idea2019\lib\idea_rt.jar=57122:F:\instrument\java\idea2019\bin -Dfile.encoding=UTF-8

查看虚拟机运行状态——jstat

jstat可以查看java虚拟机的运行时的相关信息 以及堆信息的详细情况。基本语法如下:

C:\Users\hu'nan>jstat --help
Usage: jstat --help|-options
       jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

jstat的相关参数如下:

  • option的相关参数如下:
    • -class:显示ClassLoader的相关信息。
    • -compiler:显示JIT编译的相关信息。
    • -gc:显示与GC相关的堆栈信息。
    • -gccause:显示垃圾回收相关信息,同时显示最后一次或当前正在发生的垃圾回收的原因
    • -gcnew:显示新生代信息。
    • -gcnewcapacity:显示新生代大小与使用情况。
    • -gcold:显示老年代信息。
    • -gcoldcapacity:显示老年代大小与使用情况。
    • -gcpermacapacity:显示永久代大小。
    • -gcutil:显示垃圾回收信息。
    • -printcompilation:输出JIT编译的方法信息。
  • -t参数可以在输出信息前加一个Timestamp列,显示程序的运行时间。
  • -h参数可以指定在周期性数据输出时,输出多少行数据后输出一个表头信息。
  • interval:指定输出统计数据的周期,单位为毫秒。
  • count:指定一个输出多少次数据。

示例如下:

C:\Users\hu'nan>jstat -gcnew -t -h 2 19536 1000 6
Timestamp        S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT
         2704.3    0.0 2048.0    0.0 2048.0 15  15 1024.0  12288.0   4096.0      1    0.004
         2705.3    0.0 2048.0    0.0 2048.0 15  15 1024.0  12288.0   4096.0      1    0.004
Timestamp        S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT
         2706.3    0.0 2048.0    0.0 2048.0 15  15 1024.0  12288.0   4096.0      1    0.004
         2707.3    0.0 2048.0    0.0 2048.0 15  15 1024.0  12288.0   4096.0      1    0.004
Timestamp        S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT
         2708.3    0.0 2048.0    0.0 2048.0 15  15 1024.0  12288.0   4096.0      1    0.004
         2709.3    0.0 2048.0    0.0 2048.0 15  15 1024.0  12288.0   4096.0      1    0.004

不同option参数的输出信息不同,具体的可以自行百度了解。

操作虚拟机参数——jinfo

前面我们讲了jps,了解到它的-v参数会显示传递给虚拟机的参数,这次介绍的jinfo命令更加强大,它不仅能查看虚拟机参数,而且可以在运行时修改部分参数。它的基本语法为:

C:\Users\hu'nan>jinfo --help
Usage:
    jinfo <option> <pid>
       (to connect to a running process)

jinfo相关参数如下:

  • option的相关参数如下:
    • -flag:打印java虚拟机指定参数的值。
    • -flag[+-]:设置指定Java虚拟机参数的布尔值。
    • -flag=:设置指定java虚拟机参数的值。

注意:不是所有的参数都支持使用jinfo查看,也不是所有的参数都支持动态修改。可以通过命令行或者代码获取支持动态修改的JVM参数:

  • 通过命令行获取:

    Linux环境下:java -XX:+PrintFlagsInitial | grep manageable

    Window环境下:

  • 通过API获取:HotSpotDiagnosticMXBean.getDiagnosticOptions()方法返回虚拟机支持动态修改的参数。

    public class DiagnosticOptionsTest {
    
        public static void main(String[] args) {
            HotSpotDiagnostic mxBean = new HotSpotDiagnostic();
            List<VMOption> diagnosticVMOptions = mxBean.getDiagnosticOptions();
            for (VMOption vmOption:diagnosticVMOptions){
                System.out.println(vmOption.getName() + " = " + vmOption.getValue());
            }
        }
    }
    

示例如下:

C:\Users\hu'nan>java -XX:+PrintFlagsInitial | findstr manageable
     intx CMSAbortablePrecleanWaitMillis           = 100                                    {manageable} {default}
     intx CMSTriggerInterval                       = -1                                     {manageable} {default}
     intx CMSWaitDuration                          = 2000                                   {manageable} {default}
     bool HeapDumpAfterFullGC                      = false                                  {manageable} {default}
     bool HeapDumpBeforeFullGC                     = false                                  {manageable} {default}
     bool HeapDumpOnOutOfMemoryError               = false                                  {manageable} {default}
    ccstr HeapDumpPath                             =                                        {manageable} {default}
    uintx MaxHeapFreeRatio                         = 70                                     {manageable} {default}
    uintx MinHeapFreeRatio                         = 40                                     {manageable} {default}
     bool PrintClassHistogram                      = false                                  {manageable} {default}
     bool PrintConcurrentLocks                     = false                                  {manageable} {default}

C:\Users\hu'nan>jinfo -flag HeapDumpOnOutOfMemoryError 4580
-XX:-HeapDumpOnOutOfMemoryError

C:\Users\hu'nan>jinfo -flag +HeapDumpOnOutOfMemoryError 4580

C:\Users\hu'nan>jinfo -flag HeapDumpOnOutOfMemoryError 4580
-XX:+HeapDumpOnOutOfMemoryError

导出堆到文件——jmap

jmap是一个功能强大的堆内存查看工具,它可以生成java程序的堆Dump文件,也可以查看堆内对象实例的统计信息、ClassLoader信息以及finalizer队列。jmap的基本语法为:

C:\>jmap <option> <pid>

option参数:

  • -dump:[live,]format=b,file=:使用hprof二进制形式,输出jvm的heap内容到文件(live参数是可选的,当指定了live参数时,那么只输出存活对象到文件)

  • -finalizerinfo:打印正等候回收的对象的信息。

  • -histo[:live]:打印每个class的实例数、内存占用、全限定类名。 VM的内部类名字开头会加上前缀”*”,如果加上live参数,那么只统计存活对象数量。

  • -clstats:打印Java堆的类装载器的统计信息。

示例如下:

C:\Users\hu'nan>jmap -histo 4580
 num     #instances         #bytes  class name (module)
-------------------------------------------------------
   1:          8421         958408  [B ([email protected])
   2:           643         398560  [I ([email protected])
   3:          1987         313384  [Ljava.lang.Object; ([email protected])

注意:在jdk8及以前,可以使用jhat命令分析,在jdk8之后,官方推荐使用VisualVM代替。

查看线程堆栈——jstack

jstack命令可以用于查看应用程序的堆栈。常用语法为:

C:\Users\hu'nan>jstack [-l] <pid>

-l是可选参数,指定它将会打印锁的附加信息。jstack命令会在控制台打印输出程序中所有的锁信息。

示例如下:

C:\Users\hu'nan>jstack -l 4580
2020-06-03 20:49:40
Full thread dump Java HotSpot(TM) 64-Bit Server VM (11.0.2+9-LTS mixed mode):

Threads class SMR info:
_java_thread_list=0x00000287b76019a0, length=12, elements={
0x00000287b662d800, 0x00000287b6637800, 0x00000287b6f0b000, 0x00000287b6f0c000,
0x00000287b6f0e800, 0x00000287b6f11800, 0x00000287b6647000, 0x00000287b70b3000,
0x00000287b72d0000, 0x00000287b72d4000, 0x00000287b77ba000, 0x0000028797b4d800
}

远程主机信息收集——jstatd

jstatd命令是一个RMI服务器端程序,可以通过它来建立本地计算机与远程服务器之间的通信。

jstatd参数如下:

  • -nr:当没有找到现有的RMI注册中心时,指定这个选项不会在jstatd进程中创建内部RMI注册中心。
  • -p :设置RMI注册中心的端口号,默认为1099。
  • -n :设置远程RMI对象在RMI注册表中绑定到的名称。默认名称是JStatRemoteHost。
  • -Joption/-J:此选项将Java选项传递给JVM,其中该选项是Java应用程序启动程序的参考页面中描述的选项之一。例如,-J-Xms48m将启动内存设置为48mb。

示例如下:

首先要创建一个jstatd.all.policy文件,在jdk8及以前需要写入:

grant codebase "file:F:/instrument/siki--java/java-11.0.2/lib/tools.jar" {
   permission java.security.AllPermission;
};

因为jdk11里没有tools.jar,所以需要新的配置方法:

grant codebase "jrt:/jdk.jstatd" {    
   permission java.security.AllPermission;    
};

grant codebase "jrt:/jdk.internal.jvmstat" {    
   permission java.security.AllPermission;    
};

然后在命令行运行:

C:\Users\hu'nan>jstatd -J-Djava.security.policy=F:\instrument\siki--java\java-11.0.2\conf\jstatd.all.policy
jstatd started (bound to /JStatRemoteHost)

使用jps显示远程计算机的java程序:

C:\Users\big'kai>jps 192.168.1.103:1099
4580 ApplicationStart
10056 Jps
3912
18780 Launcher

多功能指令工具——jcmd

jdk7以后新增了一个jcmd指令,它具有很多功能:导出堆、查看java进程、导出线程信息、执行GC、查看虚拟机状态等。jcmd命令可以对指定的java 虚拟机执行命令。jcmd -l会列出当前系统运行的java虚拟机。

C:\Users\hu'nan>jcmd -l
4580 cn.bigkai.ApplicationStart
18360 jdk.jcmd/sun.tools.jcmd.JCmd -l

然后可以通过jcmd help的方式列出它们所支持的指令:

C:\Users\hu'nan>jcmd 4580 help
4580:
The following commands are available:
Compiler.CodeHeap_Ana(这个词是屏蔽词。。。)lytics
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.check_commercial_features
VM.class_hierarchy
VM.classloader_stats
VM.classloaders
VM.command_line
VM.dynlibs
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 # 获取系统的properties信息
VM.systemdictionary
VM.unlock_commercial_features
VM.uptime # 查看虚拟机启动时间
VM.version
help

For more information about a specific command use 'help <command>'.

还可以通过jcmd 4580 PerfCounter.print 获取所有性能统计相关信息

你可能感兴趣的:(java,虚拟机,java)