【Java开发】之 JDK 自带的 JVM 性能调优监控工具

一、简介


JDK 本身自带了许多 JVM 调优监控工具,可以帮助我们查看 Java 应用程序的进程、线程、内存栈等信息。这些工具命令包括 jps、jstack、jmap、jhat 等等。

这些命令所在位置:

  • Linux:安装完 JDK 后,这些命令工具会默认放在 /usr/bin/ 下,直接使用即可;
  • Windows:在 Windows 下,这些命令工具在安装 Java 目录的 jdk_xxx/bin/ 目录下,比如 C:\Program Files\Java\jdk1.8.0_212\bin,如果想要在控制台上使用的话,可以将改路径添加到环境变量 Path 中。

二、命令使用介绍


1、JPS

该命令用于打印输出当前 JVM 中运行的 Java 进程状态信息,命令格式为:

jps [options] [hostid]
  • options:表示命令可选参数,支持以下选项:
    • -q:仅显示 pid
    • -m:查看进程 pidmain 方法参数;
    • -l:打印程序对应 JAR 文件所在的完整路径名;
    • -v:查看进程 pidJVM 的参数;
    • -h:打印帮助信息;
  • hostid:表示主机地址(包含协议、主机名、端口、服务名称),如果没有给出则默认为本地主机;

实例如下:

[user@localhost home]$ jps -v
1763 jar
1871 Jps -Dapplication.home=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.292.b10-1.el7_9.x86_64 -Xms8m

2、JSTACK

该命令用于查看指定 Java 进程 pid 的堆栈信息,命令格式为:

jstack [options] pid

可选参数:

  • -l:长列表展示,打印锁的附加信息;
  • -m:打印 Java 和底层 C/C++ 框架的所有栈信息;
  • -F:没有响应的时候强制打印栈信息;

实例如下:

[user@localhost home]$ jstack 1763

2022-02-28 18:21:45
Full thread dump OpenJDK 64-Bit Server VM (25.292-b10 mixed mode):

"http-nio-8888-Acceptor" #28 daemon prio=5 os_prio=0 tid=0x00007fedf8d9a000 nid=0x713 runnable [0x00007fedc69d6000]
   java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
        at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:421)
        at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:249)
        - locked <0x00000000f864cb60> (a java.lang.Object)

以上只是堆栈信息的一部分内容,从内容中可以看到线程的运行状态为 RUNNABLE,线程的运行状态有如下几种:

  • NEW:未启动,不会出现在 dump 中;
  • RUNNABLE:正在虚拟机中运行;
  • BLOCKED:被阻塞,并等待监视器锁;
  • WAITING:无限时等待其他线程释放锁;
  • TIME_WAITING:有限时的等待其他线程释放锁;
  • TERMINATED:已退出。

3、JMAP

该命令用于查看堆内存的使用情况,一般与 jhat 结合一起使用,命令格式为:

jmap [option] pid

可选参数:

  • -heap:查看进程堆内存使用情况,包括使用的 GC 算法、堆配置参数和各代中堆内存使用情况;
  • -histo[:live]:查看堆内存中的对象数目、大小统计直方图,如果带上 live 则只统计活对象;
  • -dump:format=b,file=dumpFileName:把进程内存使用情况 dump 到文件中;

实例如下:

查看堆内存情况:

[user@localhost home]$ jmap -heap 2003

Attaching to process ID 2003, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.292-b10

using thread-local object allocation.
Mark Sweep Compact GC

Heap Configuration:
   MinHeapFreeRatio         = 40
   MaxHeapFreeRatio         = 70
   MaxHeapSize              = 132120576 (126.0MB)
   NewSize                  = 2752512 (2.625MB)
   MaxNewSize               = 44040192 (42.0MB)

查看堆中对象数量:

[user@localhost home]$ jmap -histo 2003 | more

 num     #instances         #bytes  class name
----------------------------------------------
   1:         46284        4602680  [C
   2:          8592        1750048  [I
   3:         46197        1108728  java.lang.String
   4:          8416         928232  java.lang.Class
   5:         10368         912384  java.lang.reflect.Method
   6:          7634         898224  [B
   7:         25961         830752  java.util.concurrent.ConcurrentHashMap$Node
   8:         12156         486240  java.util.LinkedHashMap$Entry
   9:          6483         441904  [Ljava.util.HashMap$Node;

生成 dump 文件:

[user@localhost home]$ jmap -dump:format=b,file=/home/dump.bat 2003

Dumping heap to /home/dump.bat ...
Heap dump file created

4、JHAT

该命令用于访问 Jmap 命令生成的 dump 文件,使用浏览器访问,命令格式为:

jhat [options] <heap-dump-file>

常用可选参数:

  • -port:指定 JhatHTTP 服务端口,默认为 7000;

实例如下:

[usr@localhost home]$ jhat -port 7000 dump.bat

Reading from dump.bat...
Dump file created Mon Feb 28 19:36:58 CST 2022
Snapshot read, resolving...
Resolving 349828 objects...
Chasing references, expect 69 dots..........................................................
Eliminating duplicate references....................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

然后在浏览器中输入地址:localhost:7000IP地址以运行 Jhat 命令所在服务地址为准):

【Java开发】之 JDK 自带的 JVM 性能调优监控工具_第1张图片

5、JSTAT

该命令用于统计监测 JVM,命令格式为:

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

其中:

  • vmid:为虚拟机 ID,在 Linux/Unix 系统上一般就是进程 ID
  • interval:为采样时间间隔;
  • count:为采样数;

比如,下面命令为打印 GC 信息,采样时间间隔为 250ms,采样数为 3:

[user@localhost home]$ jstat -gc 2003 250 4
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
1408.0 1408.0  0.0    0.0   11648.0   559.7    28776.0    17264.4   42752.0 40205.1 5632.0 5149.9    172    0.399   5      0.318    0.717
1408.0 1408.0  0.0    0.0   11648.0   559.7    28776.0    17264.4   42752.0 40205.1 5632.0 5149.9    172    0.399   5      0.318    0.717
1408.0 1408.0  0.0    0.0   11648.0   559.7    28776.0    17264.4   42752.0 40205.1 5632.0 5149.9    172    0.399   5      0.318    0.717

以上各列的含义为:

  • S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used);
  • EC、EU:Eden 区容量和使用量;
  • OC、OU:年老代容量和使用量;
  • PC、PU:永久代容量和使用量;
  • YGC、YGT:年轻代 GC 次数和 GC 耗时;
  • FGC、FGCT:Full GC 次数和Full GC 耗时;
  • GCT:GC 总耗时;

我们需要明白关于 JVM 堆内存的布局关系:

  • 堆内存 = 年轻代 + 年老代 + 永久代
  • 年轻代 = Eden 区 + 两个 Survivor 区(From 和 To)

你可能感兴趣的:(Java,java,jvm)