jdk提供了一些工具,比如编译工具javac、查看堆内存快照工具jmap等,这些工具都位于 JDK 主目录的 bin 文件夹下,只要这个目录包含在系统路径中,我们就可以直接从命令行启动它们。本文介绍一下常用的jdk工具的使用方法。

1、jstack

  1. # 打印线程堆栈
  2. jstack PID | grep TID(16进制)

2、jmap

2.1 手动dump

jmap是一个工具,用于打印有关正在运行的 JVM 中的内存的统计信息。jmap中使用最多的命令是dump命令,该命令用来获取JVM中某一时刻的堆快照信息,具体使用如下:

  1. jmap -dump:[live],format=b,file=<file-path> <pid>

参数说明:

  • live:如果设置live参数,则仅打印具有活动引用的对象,并丢弃准备好进行垃圾回收的对象;
  • format:format=b意思是指定转储文件采用二进制格式,如果缺省也是默认的二进制格式;
  • file:dump文件写入的路径和文件名;
  • pid:Java进程的ID,可以用jps命令获取。

举例:

  1. jmap -dump:live,format=b,file=/tmp/dump.hprof 12587

image.png
jmap 是作为实验工具在 JDK 中引入的,可以使用Arthas工具代替,Arthas中获取dump文件的命令是heapdump
注意:dump命令仅是获取到堆内存快照,至于获取后如何分析定位问题需要用到其他工具,比如MAT。

2.2 OOM时自动抓取heap dump

2.1介绍的dump命令是在特定时间手动去dump的,在某些情况下,我们希望JVM发生OOM时自动去dump,对于这种场景jvm启动参数提供了HeapDumpOnOutOfMemoryError参数,当抛出 java.lang.OutOfMemoryError时,程序会自动生成 heap dump。具体为:

  1. java -XX:+HeapDumpOnOutOfMemoryError

默认情况下,加上HeapDumpOnOutOfMemoryError启动参数后,生成的dump文件的默认路径是当前应用程序目录中的java_pid .hprof文件中。如果要指定另一个文件或目录,可以在 HeapDumpPath参数中进行设置,如下:

  1. java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<file-or-dir-path>

HeapDumpOnOutOfMemoryErrorHeapDumpPath参数对于运行的JVM没有任何开销,建议生产环境加上此参数。

3、jstat

命令格式如下:
jstat -

  • option:必填项,如果是用jstat命令查看gc情况,则option一般是gc或者gcutil;
  • t:可选项,可以在打印的列加上时间戳列,用于显示系统运行的时间;
  • h:可选项,可以在周期性数据的时候,可以在指定输出多少行以后输出一次表;
  • vmid:java进程号,pid;
  • interval:可选项,打印的间隔时间,也可以理解为采样时间,单位为秒或者毫秒,比如1000ms,1s,带上s;
  • count:打印次数,因为jstat命令在采样期间会一直打印信息。

举例:

  1. jstat -gc -t 8 1000ms 5

3.1 查看gc情况

常用的是jstat -gc PIDjstat -gcutil PID

3.1.1 垃圾回收统计

  1. jstat -gc Java进程PID

image.png
参数说明:

  • S0C:第一个幸存区的大小
  • S1C:第二个幸存区的大小
  • S0U:第一个幸存区的使用大小
  • S1U:第二个幸存区的使用大小
  • EC:伊甸园区的大小(单位是KB,其他也一样)
  • EU:伊甸园区的使用大小
  • OC:老年代大小
  • OU:老年代使用大小
  • MC:方法区大小
  • MU:方法区使用大小
  • CCSC:压缩类空间大小
  • CCSU:压缩类空间使用大小
  • YGC:从应用程序启动到采样时间时年轻代垃圾回收次数
  • YGCT:从应用程序启动到采样时间时年轻代垃圾回收消耗时间(秒)
  • FGC:从应用程序启动到采样时间时老年代垃圾回收次数
  • FGCT:从应用程序启动到采样时间时老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

    3.1.2 堆内存统计

    1. jstat -gccapacity Java进程PID

    image.png
    参数说明:

  • NGCMN:新生代最小容量

  • NGCMX:新生代最大容量
  • NGC:当前新生代容量
  • S0C:第一个幸存区大小
  • S1C:第二个幸存区的大小
  • EC:伊甸园区的大小
  • OGCMN:老年代最小容量
  • OGCMX:老年代最大容量
  • OGC:当前老年代大小
  • OC:当前老年代大小
  • MCMN:最小元数据容量
  • MCMX:最大元数据容量
  • MC:当前元数据空间大小
  • CCSMN:最小压缩类空间大小
  • CCSMX:最大压缩类空间大小
  • CCSC:当前压缩类空间大小
  • YGC:年轻代gc次数
  • FGC:老年代GC次数

    3.1.3 新生代垃圾回收统计

    1. jstat -gcnew Java进程PID

    image.png
    参数说明:

  • S0C:第一个幸存区大小

  • S1C:第二个幸存区的大小
  • S0U:第一个幸存区的使用大小
  • S1U:第二个幸存区的使用大小
  • TT:对象在新生代存活的次数
  • MTT:对象在新生代存活的最大次数
  • DSS:期望的幸存区大小
  • EC:伊甸园区的大小
  • EU:伊甸园区的使用大小
  • YGC:年轻代垃圾回收次数
  • YGCT:年轻代垃圾回收消耗时间

    3.1.4 新生代内存统计

    1. jstat -gcnewcapacity Java进程PID

    image.png
    参数说明:

  • NGCMN:新生代最小容量

  • NGCMX:新生代最大容量
  • NGC:当前新生代容量
  • S0CMX:最大幸存1区大小
  • S0C:当前幸存1区大小
  • S1CMX:最大幸存2区大小
  • S1C:当前幸存2区大小
  • ECMX:最大伊甸园区大小
  • EC:当前伊甸园区大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代回收次数

    3.1.5 老年代垃圾回收统计

    1. jstat -gcold Java进程PID

    image.png
    参数说明:

  • MC:方法区大小

  • MU:方法区使用大小
  • CCSC:压缩类空间大小
  • CCSU:压缩类空间使用大小
  • OC:老年代大小
  • OU:老年代使用大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

    3.1.6 老年代内存统计

    1. jstat -gcoldcapacity Java进程PID

    image.png
    参数说明:

  • OGCMN:老年代最小容量

  • OGCMX:老年代最大容量
  • OGC:当前老年代大小
  • OC:老年代大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

    3.1.7 元数据空间统计

    1. jstat -gcmetacapacity Java进程PID

    参数说明:

  • MCMN: 最小元数据容量

  • MCMX:最大元数据容量
  • MC:当前元数据空间大小
  • CCSMN:最小压缩类空间大小
  • CCSMX:最大压缩类空间大小
  • CCSC:当前压缩类空间大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

    3.1.8 总垃圾回收统计

    1. jstat -gcutil Java进程PID

    image.png
    参数说明:

  • S0:幸存1区当前使用比例

  • S1:幸存2区当前使用比例
  • E:伊甸园区使用比例
  • O:老年代使用比例
  • M:元数据区使用比例
  • CCS:压缩使用比例
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

    JVM编译方法统计

    参考

    性能监控之常见 Java Heap Dump 方法
    jstat命令查看jvm的GC情况(以Linux为例)