JDK在安装的时候会提供一些性能分析、故障诊断、JVM监控之类的工具,了解这些工具对我们分析JVM内存、JVM调优有一定的帮助,本篇文章来学习一下。
监控类工具jpsjps(JVM Process Status)是查看正在运行的虚拟机进程的工具。jps能获取进程id,所以会被经常使用。在 Linux 中,一般自带了 OpenJdk,一般情况下 JPS 等命令不能用,要么选择去安装 JPS 等插件,要么把 OpenJdk 卸载,重新安装 Oracle 的 JDK。
语法:jps [ options ] [ hostid ]
- options可选项,有以下选择:
参数 | 含义 |
-q | 只显示进程 |
-m | 输出主函数传入的参数 |
-l | 输出应用程序主类完整 package 名称或 jar 完整名称. |
-v | 列出 jvm 参数 |
-V | 只生成本地JVM标识符列表 |
-J | 向JVM传递参数。例如:-J-Xms48m,设置JVM初始内存为48m |
- hostid :远程地址,可选项,指定特定主机的IP或者域名,也可以指定具体协议端口,不指定则查看当前机器的相关信息,hostid所指机器必须开启jstatd服务。
测试:
57312 JvmToolsApplication 这个是我运行的一个用于测试的springboot项目。
jstatjstat(JVM Statistics Monitoring Tool )是用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT 编译等运行数据,在没有 GUI 图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。
语法: jstat [ generalOption | outputOptions vmid [ interval[s|ms] [ count ] ]
- generalOption :常规选项,必填项。有两个参数可选 -help:帮助信息 -options:对应着下面的outputOptions
- outputOptions:输出选项,必填项。有以下选项
参数 | 含义 |
-class | 显示类加载器行为信息 |
-compiler | 显示有关JVM实时编译器行为的统计信息 |
-gc | 显示有关GC堆行为的统计信息。 |
-gccapacity | 显示各分区大小 |
-gccause | 显示最近一次 GC 统计信息和原因 |
-gcnew | 显示新生代行为的统计信息。 |
-gcnewcapacity | 显示新生代内存大小 |
-gcold | 显示老年代统计信息 |
-gcoldcapacity | 显示老年代内存大小 |
-gcmetacapacity | 显示元空间内存大小 |
-gcutil | 显示GC统计汇总信息 |
-printcompilation | 显示HotSpot 编译统计信息 |
outputOptions参数后面还能加以下可选参数:
- -h n:每n个样本(输出行)显示一个列标题,默认值为0,显示列标题的第一行数据。
- -t:第一列显示为时间戳
- -J:向应用程序传递启动参数
复制代码
- VMid :虚拟机标识
- interval:指定时间采样间隔时间,单位秒(s)或者毫秒(ms),默认单位是毫秒
- count :采样次数,指定时间内采样多少次。
测试:
- 统计gc信息 57312 是测试项目JvmToolsApplication在虚拟机中的进程id。
- jstat -gc 57312 100 10这个命令是在100ms内获取10次gc统计信息 结果中的列分别代表以下意思:
- S0C:第一个幸存区(From 区)的大小
- S1C:第二个幸存区(To 区)的大小
- S0U:第一个幸存区的使用大小
- S1U:第二个幸存区的使用大小
- EC:伊甸园(Eden)区的大小
- EU:伊甸园(Eden)区的使用大小
- OC:老年代大小
- OU:老年代使用大小
- MC:方法区大小
- MU:方法区使用大小
- CCSC:压缩类空间大小
- CCSU:压缩类空间使用大小
- YGC:年轻代垃圾回收次数
- YGCT:年轻代垃圾回收消耗时间
- FGC:老年代垃圾回收次数
- FGCT:老年代垃圾回收消耗时间
- GCT:垃圾回收消耗总时间
jinfo(Configuration Info for java) 可以实时地查看和调整虚拟机的各项参数。jinfo不仅能获取到虚拟机命令行参数,还能获取到系统参数。
语法:
- jinfo [ option ] pid:查看和调整本地进程虚拟机参数
option:
- -flag name:name为jvm参数名
- -flag [ |-]name:开启或者关闭一个Boolean的jvm参数
- -flag name=value:设置jvm参数值
- -Flags:查询虚拟机参数
- -sysprops:可以查看由 System.getProperties()取得的参数
测试:
- flag测试 可以通过java -XX: PrintFlagsFinal –version命令获取虚拟机参数,这是一个很长的列表,其中红框部分如果是manageable则表示可以在运行时修改。 我们就随便找一个参数UseTLAB进行查询,可以看到它是否开启
- 获取虚拟机参数 先修改一下项目启动参数,加上-XX: PrintGC -XX:SurvivorRatio=6: 重启项目,并通过jps获取到进程id 再通过jinfo -flags 67776命令获取项目启动参数 还可以获取上面配置的某一个参数jinfo -flag SurvivorRatio 67776
通过 jinfo 命令,我们可以在生产上临时打开一下 GC日志或者进行一些数据的配置(不需要重启应用条件下),也是我们去排查问题的一个关键命令。
jmapjmap(Memory Map for Java) 打印给定进程或远程调试服务器的共享对象内存映射或堆内存详细信息。jmap也可用于生成堆转储快照(一般称为 heapdump 或 dump 文件),除此之外它还可以查询 finalize 执行队列、Java 堆和永 久代的详细信息,如空间使用率、当前用的是哪种收集器等。和 jinfo 命令一样,jmap 有不少功能在 Windows 平台下都是受限的,除了生成 dump 文件的 -dump 选项和用于查看每个类的实例、空间占用统计的-histo 选项在所有操作系统都提供之外,其余选项都只能在 Linux/Solaris 下使用。
语法:jmap [ options ] pid
options 有如下选项:
- -heap:打印 heap 的概要信息 概要信息含义:
Heap Configuration: ##堆配置情况,也就是 JVM 参数配置的结果[平常说的 tomcat 配置 JVM 参数,就是在配置这些]
MinHeapFreeRatio = 0 //最小堆使用比例
MaxHeapFreeRatio = 100 //最大堆可用比例
MaxHeapSize = 4261412864 (4064.0MB) //最大堆空间大小
NewSize = 88604672 (84.5MB) ) //新生代分配大小
MaxNewSize = 1420296192 (1354.5MB) //最大可新生代分配大小
OldSize = 177733632 (169.5MB) //老年代大小
NewRatio = 2 //新生代比例
SurvivorRatio = 6 //新生代与 suvivor 的比例
MetaspaceSize = 21807104 (20.796875MB) //元空间大小
CompressedClassSpaceSize = 1073741824 (1024.0MB) //类指针压缩空间大小
MaxMetaspaceSize = 17592186044415 MB // 最大元空间大小
G1HeapRegionSize = 0 (0.0MB) //G1收集器Region单元大小
Heap Usage: //堆内存实际的使用情况
PS Young Generation //新生代
Eden Space: //Eden 区
capacity = 66584576 (63.5MB) //Eden容量
used = 27941200 (26.646804809570312MB) //Eden区已使用大小
free = 38643376 (36.85319519042969MB) //未使用
41.96347214105561% used //使用比例
From Space: //survior1 区
capacity = 11010048 (10.5MB)
used = 8497840 (8.104171752929688MB)
free = 2512208 (2.3958282470703125MB)
77.18258812313988% used
To Space: //survior2 区
capacity = 11010048 (10.5MB)
used = 0 (0.0MB)
free = 11010048 (10.5MB)
0.0% used
PS Old Generation //老年代使用情况
capacity = 115867648 (110.5MB)
used = 10553152 (10.06427001953125MB)
free = 105314496 (100.43572998046875MB)
9.10793666925905% used
复制代码
- -histo 打印每个 class 的实例数目,内存占用,类全名信息. 语法:jmap –histo:live <pid>,live参数表示统计活跃状态的对象 -histo 打印的实例数目太多了,看不过来,显示那么多也没什么用,所以在Linux系统上可以使用jmap –histo <pid> | head -10命令只展示前10行,具体行数可以自己定义。
- -finalizerinfo :打印正等候回收的对象的信息
- –clstats:打印堆中类加载器信息,它会打印类加载器的名字、活跃度、地址、父加载器、加载了多少个类等。
- -dump:[live,] format=b, file=filename:生成的堆转储快照 通过-dump命令可以在指定文件夹生成dump文件,之后再搭配jhat来分析dump文件,dump文件的后缀也可以是hprof 或者bin,dump文件本身是一个二进制文件。
- -h或-help:打印帮助信息
- -J:传递虚拟机参数
jhat (Heap Dump Browser)可以让一个dump文件以web服务的的形式访问。
上面我们用jmap工具生成了一个dump文件,现在可以通过jhat 工具,让它再浏览器端访问到。
Server is ready表示启动成功,端口号为7000,然后在浏览器端访问http://localhost:7000/,可以看到dump文件内容