JVM监控诊断之命令行使用

Posted ProChick

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM监控诊断之命令行使用相关的知识,希望对你有一定的参考价值。

在刚开始学习Java的时候,我们肯定对javacjava两个命令非常熟悉。但其实在JDK中,Oracle官方还给我们提供了许多辅助命令工具,也都在安装JDK的bin目录下,这些辅助命令工具大都是用来获取JVM不同方面、不同层次的信息,帮助开发人员能够更好的解决应用程序中出现的一些疑难杂症。

1.jps命令

jps(Java Process Status),用于查询正在运行的虚拟机进程或是Java应用程序进程

  • 基本使用

    🎈:左边是进程号,右边是进程名称

    👉:这里显示的本地虚拟机进程ID,其实和本地操作系统的进程ID是一致的,都是唯一的。

    👉:如果在Java进程启动时,使用了-XX:-UserPerfData参数,即关闭默认开启的UserPerfData参数的话,那么jps命令则无法探测该Java进程。

  • 参数使用

    • jps -q

      💡:只显示本地虚拟机进程ID

    • jps -l

      💡:显示应用程序主类的全类名

    • jps -m

      💡:显示虚拟机启动时,传递给各应用程序的参数

    • jps -v

      💡:显示虚拟机启动时设置的JVM参数

    • jps -options -hostid

      💡:显示远程主机上的Java虚拟机进程信息

2.jstat命令

jstat(Java Statistics Monitoring Tool),用于监视虚拟机各种运行状态信息,显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。

  • 基本参数

    • jstat -class

      💡:显示类加载的相关信息,包括类的装载数量、类的卸载数量、类装载所消耗的时间等

    • jstat -gc

      💡:显示与GC相关的堆区间信息,包括Eden区、Survivor区、老年代、永久代的总容量、已使用空间等信息

      • S0C:第一个幸存者区的总大小,单位为字节
      • S1C:第二个幸存者区的总大小,单位为字节
      • S0U:第一个幸存者区的已使用大小,单位为字节
      • S1U:第二个幸存者区的已使用大小,单位为字节
      • EC:Eden区的总大小,单位为字节
      • EU:Eden区的已使用大小,单位为字节
      • OC:老年代的总大小,单位为字节
      • OU:老年代的已使用大小,单位为字节
      • MC:方法区的总大小,单位为字节
      • MU:方法区的已使用大小,单位为字节
      • CCSC:压缩类空间的总大小,单位为字节
      • CCSU:压缩类空间的已使用大小,单位为字节
      • YGC:从程序启动开始,发生Young GC的次数
      • YGCT:Young GC的耗时,单位为秒
      • FGC:从程序启动开始,发生Full GC的次数
      • FGCT:Full GC的耗时,单位为秒
      • GCT:从程序启动开始,所有GC发生的总耗时,单位为秒
    • jstat -gccapacity

      💡:显示与GC相关的堆空间中各个区域的最大空间、最小空间等信息

    • jstat -gcutil

      💡:显示与GC相关的堆空间中各个区域的已使用空间占比信息

    • jstat -gccause

      💡:显示情况与上面的命令类似,不过会输出导致发生GC的原因

    • jstat -gcnew

      💡:显示年轻代GC的垃圾回收信息

    • jstat -gcnewcapacity

      💡:显示年轻代使用的最大空间、最小空间等信息

    • jstat -gcold

      💡:显示老年代GC的垃圾回收信息

    • jstat -gcoldcapacity

      💡:显示老年代使用的最大空间、最小空间等信息

    • jstat -gcpermcapacity

      💡:显示永久代使用的最大空间、最小空间等信息

    • jstat -compiler

      💡:显示JIT编译器编译过的方法、耗时等信息

    • jstat -printcompilation

      💡:显示已经被JIT编译器编译的方法

  • 附加参数

    • jstat -option -interval

      💡:指定输出统计数据的间隔时间,单位为毫秒,也就是每隔多少毫秒打印一次信息

    • jstat -option -count

      💡:指定输出统计数据的次数

    • jstat -option -t

      💡:显示程序当前运行的总时间,单位为秒

    • jstat -option -h

      💡:指定输出多少行数据时,输出一下表头信息

  • 实际场景

    • 判断是否出现内存溢出
      • 在程序的运行过程中,在某段时间内使用jstat命令连续获取多行监控数据,计算这段时间中程序的运行时间以及总的发生GC的时间,然后进行对比。
      • 如果GC发生的时间占据了程序运行总时间的90%以上,则说明很有可能要发生OOM异常。
    • 判断是否出现内存泄露
      • 在程序的运行过程中,在某段时间内使用jstat命令连续获取多行监控数据,然后取出老年代当前占用空间(OU)的最小值。
      • 每隔一段时间就提取出上面提到的OU最小值,然后进行对比。如果发现该值在不断的上涨,这说明在进行GC时,很多存在于老年代的对象根本无法回收,所以也就有可能发生了内存泄露。

3.jinfo命令

jinfo(Configuration Info For Java),用于查看Java虚拟机的相关参数信息,也可用来调整Java虚拟机中的参数配置。

  • 查看相关

    • java -XX:+PrintFlagsInital

      💡:显示JVM启动时所有参数时的默认值

    • java -XX:+PrintFlagsFinal

      💡:显示JVM启动时所有参数时的最终值

    • java -XX:+PrintCommandLineFlags

      💡:显示JVM启动时被用户修改后的参数信息

    • jinfo -sysprops

      💡:显示由System.getProperties()方法可以获取到的参数信息

    • jinfo -flags

      💡:显示当前运行程序中JVM已设置的参数信息

    • jinfo -flag

      💡:显示当前运行程序中JVM已设置的指定参数信息

  • 设置相关

    • jinfo -flag +/-name

      💡:对Boolean类型的JVM参数进行设置

    • jinfo -flag name=value

      💡:对非Boolean类型的JVM参数进行设置

4.jmap命令

jmap(JVM Memory Map),可用于获取堆转储快照文件(dump文件),获取Java进程的内存使用情况,获取堆空间各个区域的使用情况,获取堆空间中对象的统计信息,获取类加载的信息等等。

  • 基本参数

    • jmap -dump

      💡:生成堆转储dump文件

    • jmap -heap

      💡:显示整个堆空间的详细信息,包括GC的使用、堆的配置、内存的使用

    • jmap -histo

      💡:显示堆空间中对象的统计信息,包括类、实例变量

    • jmap -permstat

      💡:显示永久代的内存状态信息,仅在Linux/Solaris系统平台中有效

    • jmap -finalizerinfo

      💡:显示正在等待Finalizer线程执行finalize方法的对象信息,仅在Linux/Solaris系统平台中有效

    • jmap -F

      💡:强制执行命令,仅在Linux/Solaris系统平台中有效

    • jmap -J

      💡:传递参数给jmap启动的JVM

  • 具体使用

    • 导出内存映像文件

      Heap Dump又叫做堆转储文件,指的是某个Java进程在某个时间点的内存快照,内容主要包括所有的类信息、对象信息、垃圾回收器信息、线程栈帧和局部变量表等信息。

      🎈:在生成该文件之前,通常会触发一次Full GC,并且生成的过程比较耗时。

      手动生成方式

      # 生成dump文件
      jmap -dump:fromat=b,file=xxx.hprof <pid>
      
      # 生成dump文件(只包含存活的对象信息)
      jmap -dump:live,fromat=b,file=xxx.hprof <pid>
      

      自动生成方式

      # 在JVM启动参数设置中开启此功能,当程序发生OOM异常时,自动导出dump文件到指定位置
      -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:/xxx.hprof
      
    • 展示堆内存相关信息

      # 堆空间各个区域的使用情况
      jmap -heap <pid>
      
      # 堆空间中对象内存占用情况
      jmap -histo <pid>
      

  • 注意事项

    • 由于jmap在执行时,会访问堆空间中的所有对象,所以为了保证在此过程中不被应用线程干扰,jmap需要借助安全点机制,让所有的线程停留在不改变堆中数据的状态。
    • 如果某个线程长时间无法到达安全点,那么jmap在运行时将会一直等待。

5.jhat命令

jhat(JVM Heap Analysis Tool),可用于对堆转储快照文件(dump文件)进行分析,其内部内置了一个微型的HTTP服务器,以便将分析的结果以页面的形式呈现在浏览器上,我们可以通过访问本地7000端口进行查看。

  • 基本参数

    • jhat -stack false|true

      💡:显示或关闭对象分配调用栈跟踪

    • jhat -refs false|true

      💡:显示或关闭对象引用跟踪

    • jhat -port

      💡:设置jhat内置HTTP服务器的启动端口号

    • jhat -exclude

      💡:指定执行对象查询时需要排除的数据成员

    • jhat -baseline

      💡:指定一个基准堆转储文件

    • jhat -debug

      💡:设置分析时所用debug的级别

    • jhat -version

      💡:显示jhat的版本信息

    • jhat -J

      💡:为jhat设置启动参数

  • 注意事项

    • 该命令在JDK9、JDK10中已被删除。

6.jstack命令

jstack(JVM Stack Trace),用于生成指定Java应用程序进程的某一时刻的线程快照,包含了当前线程正在执行方法的堆栈集合,可用于分析线程出现长时间阻塞等待的原因。

  • 基本使用

  • 参数使用

    • jstack -F

      💡:当正常输出的请求不被响应时,强制输出线程堆栈信息

    • jstack -l

      💡:额外显示关于锁的附加信息

    • jstack -m

      💡:当程序调用本地方法时,额外显示C/C++的堆栈信息

7.jcmd命令

jcmd是一个多功能命令行工具,可以用来实现前面所描述的指令的大部分功能,比如:导出堆转储文件、查看内存使用情况、查看GC执行信息、查看JVM运行时间等等。

  • 参数使用

    • jstack -l

      💡:显示所有的JVM进程信息

    • jstack <进程ID> help

      💡:显示指定进程所能够支持的所有命令

    • jstack <进程ID> <具体指令>

      💡:显示指定进程使用指定指令后的输出信息

8.jstatd命令

  • 在上面我们所描述的一些监控命令中,有一些是支持对远程计算机的应用程序进行监控的,比如:jps、jstat,但是它们还需要配合使用jstatd命令工具才能实现远程监控。

  • jstatd命令工具是一个RMI服务端程序,它的作用相当于代理服务器,用于建立本地计算机和远程计算机之间的通信桥梁。

以上是关于JVM监控诊断之命令行使用的主要内容,如果未能解决你的问题,请参考以下文章

JVM监控诊断之命令行使用

JVM监控诊断之工具使用(上篇)

JVM监控诊断之工具使用(上篇)

JVM监控诊断之工具使用(上篇)

JVM监控诊断之工具使用(上篇)

JVM监控及诊断工具-命令之jcmd