当前位置: 代码迷 >> 综合 >> GC调优基础知识之工具篇--jdk为我们提供的命令行命令 jps,jstat,jmap,jinfo,jstat,jstack,jhat 等
  详细解决方案

GC调优基础知识之工具篇--jdk为我们提供的命令行命令 jps,jstat,jmap,jinfo,jstat,jstack,jhat 等

热度:87   发布时间:2023-12-25 02:43:31.0

一. JDK为我们提供的工具:

在这里插入图片描述

?? 在Windows中对于这些命令的支持是源自JDK -->bin下面的.exe可执行文件的支持。
![(https://img-blog.csdnimg.cn/20200819213214131.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4Njc1Mzcz,size_16,color_FFFFFF,t_70#pic_center)
?? 在Linux中对于这些命令的支持是源自JDK -->bin下面可执行文件的支持。
在这里插入图片描述

二. 命令解析

2.1 jps

?? 列出当前机器上正在运行的虚拟机进程,JPS从操作系统的临时目录上去找(所以有一些信息可能显示不全)。

jps 常用参数 参数意义
-l 输出应用程序主类完整 package 名称或 jar 完整名称.
-q 仅仅显示进程 pid
-v 列出 jvm 参数, -Xms20m -Xmx50m 是启动程序指定的 jvm 参数
-m 输出主函数传入的参数

eg: jps -l
在这里插入图片描述

2.2 jstat

?? 用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT 编译等运行数据。在没有 GUI 图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。

jstat 选项(Options) 作用
-class 监视类装载、卸载数量、总空间及类装载所耗费的时间
-gc 监视Java堆状况,包括Eden区、2个survivor区、老年代、永久代等的容量、用空间、GC时间合计等时间
-gcutil 监视内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比
-gccapacity 监视内容与 -gc基本相同,但输出主要关注Java堆各个区域使用到的最大和最小空间
-gccause -gcutil功能一样,但是会额外输出导致上次GC产生的原因
-gcnew 监视新生代GC的状况
-gcnewcapacity 监视内容与 -gcnew基本相同,输出主要关注使用到的最大和最小空间
-gcold 监视老年代GC的状况
-gcoldcapacity 监视内容与-gccold基本相同,输出主要关注使用到的最大和最小空间
-gcpermcapacity 输出永久代使用到的最大和最小空间
gcmetacapacity 显示有关元空间大小的统计信息
-compiler 输出JIT编译器编译过的方法、耗时等信息
-printcompilation HotSpot 编译统计(已经被JIT编译的方法)

2.2.1 语法规则

??jstat [Options] vmid [interval] [count]

  • Options:选项
  • vmid:VM的进程号,即当前运行的java进程号(pid)
  • interval:采样间隔,单位为秒(s)或毫秒(ms)。默认单位是毫秒。必须为正整数。指定后,该jstat命令将在每个间隔产生其输出。
  • count:打印次数,如果缺省则打印无数次

2.2.2 特别说明之 jstat -class pid

?? eg: jstat -class pid
在这里插入图片描述

-class选项输出列 释义
Loaded 已经加载的类的个数
Bytes 已经加载类的大小(左边第一个Bytes)
Unloaded 未加载类的个数
Bytes 未加载类的大小(右边第一个Bytes)
Time 加载类消耗的时间

2.2.3 特别说明之 jstat -gc pid

在这里插入图片描述
亦可每秒刷新一次,输出50次:jstat -gc 18787 1000 50

-gc选项输出列 参数意义
S0C 年轻代中第一个survivor(幸存区)的容量 (字节)
S1C 年轻代中第二个survivor(幸存区)的容量 (字节)
S0U 年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
S1U 年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
EC 年轻代中Eden(伊甸园)的容量 (字节)
EU 年轻代中Eden(伊甸园)目前已使用空间 (字节)
OC Old代的容量 (字节)
OU Old代目前已使用空间 (字节)
MC 方法区大小 (字节)
MU 方法区使用大小 (字节)
CCSC 压缩类空间大小(字节)
CCSU 压缩类空间使用大小(字节)
YGC 从应用程序启动到采样时年轻代中gc次数
YGCT 从应用程序启动到采样时年轻代中gc所用时间(s)
FGC 从应用程序启动到采样时old代(全gc)gc次数
FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT 从应用程序启动到采样时gc用的总时间(s)

2.3 jinfo

?? 查看和修改虚拟机的参数 (高级参数是否能修改在2.4中介绍)
语法:
jinfo [ option ] pid

jinfo option 作用
no-option Prints both command-line flags and system property name-value pairs.
同时打印命令行标志和系统属性名称-值对
-flag name Prints the name and value of the specified command-line flag.
打印未被显式指定参数的系统默认值
-flag [+|-]name enables or disables the specified Boolean command-line flag.
启用或禁用指定的布尔命令行标志。
-flag name=value Sets the specified command-line flag to the specified value.
将指定的命令行标志设置为指定的值。
-flags Prints command-line flags passed to the JVM.
打印传递给JVM的命令行标志。(显示虚拟机的参数)
-sysprops Prints Java system properties as name-value pairs.
将Java系统属性打印为名称-值对
可以查看由 System.getProperties()取得的参数

eg:

  • 添加GC日志打印
    ?? jinfo -flag +PrintGC 24762
  • 查看打印 GC 详情
    ?? jinfo -flag PrintGC 24762
  • 取消打印 GC 详情
    ?? jinfo -flag -PrintGC 24762
    在这里插入图片描述

2.4 VM参数

?? VM参数是虚拟机可配置的参数,通过这些参数,我们可以了解虚拟机的运行时的参数配置,有助于我们了解虚拟机的运行状态。可分为以下6种:
在这里插入图片描述

2.4.1 Standard Options 标准选项

?? 标准选项: -options,所有的HotSpot都支持
在这里插入图片描述
在这里插入图片描述

2.4.2 Non-Standard Options 非标准选项

?? 非标准选项 -Xoptions,特定版本 HotSpot 支持特定命令 非标准选项是特定于 Java HotSpot 虚拟机的通用选项。因此不能保证所有 JVM 实现都支持它们,并且它们可能会发生变化,这些选项以开头-X。eg: -Xms30m -Xmx30m -Xss1m

在这里插入图片描述

在这里插入图片描述

2.4.3 Advanced Runtime Options 高级选项

?? 高级选项:以开头-XX: 这些是开发人员选项,用于调整 Java HotSpot 虚拟机操作的特定区域,这些区域通常具有特定的系统要求,并且可能需要对系统配置参数的特权访问。也不能保证所有 JVM 实现都支持它们,并且它们可能会发生变化。
在这里插入图片描述
在这里插入图片描述

2.4.4 VM高级参数命令行中查找

?? 可以在windows中通过java -XX:+PrintFlagsFinal -version查看
在这里插入图片描述

  • 第一列:配置参数的属性 布尔、int等;
  • 第二列:配置参数名;
  • 第三列:配置参数的默认值;
  • 第四列:配置参数是否可以再运行时修改生效等(product 不能,manageable 可以)。

?? 其他的就不在做过多的介绍,有兴趣可以自行查看Oracle jdk8官方文档

2.5 jmap

?? 用于生成堆转储快照(一般称为 heapdump 或 dump 文件)。jmap 的作用并不仅仅是为了获取 dump 文件,它还可以查询 finalize 执行队列、Java 堆和永 久代的详细信息,如空间使用率、当前用的是哪种收集器等。和 jinfo 命令一样,jmap 有不少功能在 Windows 平台下都是受限的,除了生成 dump 文件的 -dump 选项和用于查看每个类的实例、空间占用统计的-histo 选项在所有操作系统都提供之外,其余选项都只能在 Linux/Solaris 下使用。
在这里插入图片描述

jmap options 作用
no option When no option is used, the jmap command prints shared object mappings. For each shared object loaded in the target JVM, the start address, size of the mapping, and the full path of the shared object file are printed. This behavior is similar to the Oracle Solaris pmap utility.
-dump:[live,] format=b, file=filename Dumps the Java heap in hprof binary format to filename. The live suboption is optional, but when specified, only the active objects in the heap are dumped. To browse the heap dump, you can use the jhat(1) command to read the generated file.
-finalizerinfo Prints information about objects that are awaiting finalization.
-heap Prints a heap summary of the garbage collection used, the head configuration, and generation-wise heap usage. In addition, the number and size of interned Strings are printed.
-histo[:live] Prints a histogram of the heap. For each Java class, the number of objects, memory size in bytes, and the fully qualified class names are printed. The JVM internal class names are printed with an asterisk (*) prefix. If the live suboption is specified, then only active objects are counted.
-clstats Prints class loader wise statistics of Java heap. For each class loader, its name, how active it is, address, parent class loader, and the number and size of classes it has loaded are printed.
-F Force. Use this option with thejmap -dumporjmap -histooption hen the pid does not respond. The live suboption is not supported in this mode.

2.5.1jmap -heap pid 使用

在这里插入图片描述

配置信息父级 配置信息子级 说明
Heap Configuration: 堆配置情况,也就是 JVM 参数配置的结果
[平常说的tomcat配置JVM参数,就是在配置这些]
MinHeapFreeRatio = 40 最小堆使用比例
MaxHeapFreeRatio = 70 最大堆可用比例
MaxHeapSize = 2147483648 (2048.0MB) 最大堆空间大小
NewSize = 697892864 (665.5625MB) 新生代分配大小
MaxNewSize = 697892864 (665.5625MB) 最大可新生代分配大小
OldSize = 1449590784 (1382.4375MB) 老年代大小
NewRatio = 2 新生代比例
SurvivorRatio = 8 新生代与suvivor 的比例
PermSize = 134217728 (128.0MB) jdk7 perm 区 永久代大小
MaxPermSize = 134217728 (128.0MB) jdk7 最大可分配 perm 区 也就是永久代大小
MetaspaceSize= 125829120 (120.0MB) jdk8 方法区初始化大小
MaxMetaspaceSize = 536870912 (512.0MB) jdk8 方法区最大大小
G1HeapRegionSize = 0 (0.0MB) 设置垃圾回收器G1的堆大小
Heap Usage: 堆使用情况【堆内存实际的使用情况】
New Generation (Eden + 1 Survivor Space): 新生代(伊甸区Eden区 + 幸存区survior(1+2)空间)
capacity = 628162560 (599.0625MB) 伊甸区容量
used = 482172504 (459.83553314208984MB) 已经使用大小
free = 145990056 (139.22696685791016MB) 剩余容量
76.75919176080791% used 使用比例
Eden Space: 伊甸区
capacity = 558432256 (532.5625MB) 伊甸区容量
used = 476784440 (454.6970748901367MB) 伊甸区使用
free = 81647816 (77.86542510986328MB) 伊甸区当前剩余容量
85.37910102384917% used 伊甸区使用情况
From Space: survior0 区
capacity = 69730304 (66.5MB) survior1 区容量
used = 5388064 (5.138458251953125MB) surviror1 区已使用情况
free = 64342240 (61.361541748046875MB) surviror1 区剩余容量
7.727004890155075% used survior1 区使用比例
To Space: survior1 区
capacity = 69730304 (66.5MB)
used = 0 (0.0MB) survior2 区已使用情况
free = 69730304 (66.5MB) survior2 区剩余容量
0.0% used survior2 区使用比例
concurrent mark-sweep generation: 当前老年代使用标记清除算法
capacity = 1449590784 (1382.4375MB) 老年代容量
used = 852234240 (812.75390625MB) 老年代已使用容量
free = 597356544 (569.68359375MB) 老年代剩余容量
58.79136715041367% used 老年代使用比例

2.5.2jmap -histo

  • jmap -histo 打印每个 class 的实例数目,内存占用,类全名信息.
  • jmap –histo:live 如果 live 子参数加上后,只统计活的对象数量.

?? 但是这样显示太多了,一般在 linux 上会这么操作 jmap –histo 1196 | head -50 (显示排名前 20 的数据)
jps

不太重要的参数 -finalizerinfo 打印正等候回收的对象的信息,还有 jmap –clstats 这个命令最好也不要去使用
在这里插入图片描述

-dump 生成的堆转储快照(比较重要) jmap -dump:live,format=b,file=heap.bin Sun JDK 提供 jhat(JVM Heap Analysis Tool)命令与 jmap 搭配使用,来分析 jmap 生成的堆转储快照。
在这里插入图片描述

2.6 jhat

jhat dump 文件名 后屏幕显示“Server is ready.”的提示后,用户在浏览器中键入 http://localhost:7000/就可以访问详情
在这里插入图片描述

? ? 使用 jhat 可以在服务器上生成堆转储文件分析(一般不推荐,毕竟占用服务器的资源,比如一个文件就有 1 个 G 的话就需要大约吃一个 1G 的内存资源)

2.7 jstack

? ? (Stack Trace for Java)命令用于生成虚拟机当前时刻的线程快照。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主 要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等都是导致线程长时间停顿的常见原因。
? ? 在代码中可以用 java.lang.Thread 类的 getAllStackTraces()方法用于获取虚拟机中所有线程的 StackTraceElement 对象。使用这个方法可以通过简单的几行 代码就完成 jstack 的大部分功能,在实际项目中不妨调用这个方法做个管理员页面,可以随时使用浏览器来查看线程堆栈。(并发编程中的线程安全课程 中有具体的案例)

? ? 一般来说 jstack 主要是用来排查是否有死锁的情况,这块内容在并发编程(包括二期)中有详细的讲解
在这里插入图片描述

在这里插入图片描述

三. 命令工具总结

3.1 生产服务器推荐开启

?? -XX:-HeapDumpOnOutOfMemoryError默认关闭,建议开启,在 java.lang.OutOfMemoryError 异常出现时,输出一个 dump 文件,记录当时的堆内存快照。
? ? -XX:HeapDumpPath=./java_pid<pid>.hprof用来设置堆内存快照的存储文件路径,默认是 java 进程启动位置。

3.2 调优之前开启、调优之后关闭

? ? -XX:+PrintGC
? ? 调试跟踪之 打印简单的 GC 信息参数:
? ? -XX:+PrintGCDetails, +XX:+PrintGCTimeStamps
? ? 打印详细的 GC 信息
? ? -Xlogger:logpath
? ? 设置 gc 的日志路,如: -Xlogger:log/gc.log, 将 gc.log 的路径设置到当前? ? 目录的 log 目录下.
? ? 应用场景: 将 gc 的日志独立写入日志文件,将 GC 日志与系统业务日志进行了分离,方便开发人员进行追踪分析。

3.3 考虑使用

-XX:+PrintHeapAtGC, 打印堆信息
? ? 参数设置: -XX:+PrintHeapAtGC
? ? 应用场景: 获取 Heap 在每次垃圾回收前后的使用状况
-XX:+TraceClassLoading
? ? 参数方法: -XX:+TraceClassLoading
? ? 应用场景: 在系统控制台信息中看到 class 加载的过程和具体的 class 信息,可用以分析类的加载顺序以及是否可进行精简操作。 -XX:+DisableExplicitGC 禁止在运行期显式地调用 System.gc()

  相关解决方案