[转帖]JVM监控和诊断工具

jvm,监控,诊断,工具 · 浏览次数 : 0

小编点评

**jstat** * 显示正在运行的 Java 进程的信息,包括类加载、编译状态和垃圾回收信息。 * 允许用户查看目标 Java 进程的堆中存放的 Java 对象数量和导出成二进制文件。 * 提供用于检测内存泄漏问题的工具,例如堆图和类加载图。 * 可以用于检测死锁的工具,例如打印线程的栈轨迹和死锁信息。 **jmap** * 允许用户统计目标 Java 进程的堆中存放的 Java 对象数量。 * 可导出 Java 对象数量数据到二进制文件。 * 提供用于分析 Java 进程配置参数的工具。 **其他工具** * **jinfo**:显示目标 Java 进程的配置参数。 * **jstack**:打印目标 Java 进程中各个线程的栈轨迹。 * **jcmd**:显示 Java 进程启动时加载的类数量。

正文


目录

作者:@dwtfukgv
本文为作者原创,转载请注明出处:https://www.cnblogs.com/dwtfukgv/p/15126148.html

JVM监控和诊断工具

jps

它将打印所有正在运行的Java进程的相关信息。

在默认情况下,jps的输出信息包括Java进程的进程ID以及主类名。我们还可以通过追加参数,来打印额外的信息。例如,-l将打印模块名以及包名;-v将打印传递给Java虚拟机的参数(如-XX:+UnlockExperimentalVMOptions -XX:+UseZGC);-m将打印传递给主类的参数。

需要注意的是,如果某Java进程关闭了默认开启的UsePerfData参数(即使用参数-XX:-UsePerfData),那么jps命令(以及下面介绍的jstat)将无法探知该Java进程。

  $ jps -mlv
  18331 org.example.Foo Hello World
  18332 jdk.jcmd/sun.tools.jps.Jps -mlv -Dapplication.home=/Library/Java/JavaVirtualMachines/jdk-11.jdk/Contents/Home -Xms8m -Djdk.module.main=jdk.jcmd

jstat

它可用来打印目标Java进程的性能数据。它包括多条子命令,如下所示:

  $ jstat -options
  -class
  -compiler
  -gc
  -gccapacity
  -gccause
  -gcmetacapacity
  -gcnew
  -gcnewcapacity
  -gcold
  -gcoldcapacity
  -gcutil
  -printcompilation

在这些子命令中,-class将打印类加载相关的数据,-compiler-printcompilation将打印即时编译相关的数据。剩下的都是以-gc为前缀的子命令,它们将打印垃圾回收相关的数据。

默认情况下,jstat只会打印一次性能数据。我们可以将它配置为每隔一段时间打印一次,直至目标Java进程终止,或者达到我们所配置的最大打印次数。具体示例如下所示:

  # Usage: jstat -outputOptions [-t] [-hlines] VMID [interval [count]]
  $ jstat -gc 22126 1s 4
  S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT CGC CGCT GCT
  17472,0 17472,0 0,0 0,0 139904,0 47146,4 349568,0 21321,0 30020,0 28001,8 4864,0 4673,4 22 0,080 3 0,270 0 0,000 0,350
  17472,0 17472,0 420,6 0,0 139904,0 11178,4 349568,0 21321,0 30020,0 28090,1 4864,0 4674,2 28 0,084 3 0,270 0 0,000 0,354
  17472,0 17472,0 0,0 403,9 139904,0 139538,4 349568,0 21323,4 30020,0 28137,2 4864,0 4674,2 34 0,088 4 0,359 0 0,000 0,446
  17472,0 17472,0 0,0 0,0 139904,0 0,0 349568,0 21326,1 30020,0 28093,6 4864,0 4673,4 38 0,091 5 0,445 0 0,000 0,536

在上面这个示例中,22126进程是一个使用了CMS垃圾回收器的Java进程。我们利用jstat-gc子命令,来打印该进程垃圾回收相关的数据。命令最后的1s 4表示每隔1秒打印一次,共打印4次。在-gc子命令的输出中,前四列分别为两个Survivor区的容量(Capacity)和已使用量(Utility)。我们可以看到,这两个Survivor区的容量相等,而且始终有一个Survivor区的内存使用量为0。当使用默认的G1 GC时,输出结果则有另一些特征:

  $ jstat -gc 22208 1s
  S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT CGC CGCT GCT
  0,0 16384,0 0,0 16384,0 210944,0 192512,0 133120,0 5332,5 28848,0 26886,4 4864,0 4620,5 19 0,067 1 0,016 2 0,002 0,084
  0,0 16384,0 0,0 16384,0 210944,0 83968,0 133120,0 5749,9 29104,0 27132,8 4864,0 4621,0 21 0,078 1 0,016 2 0,002 0,095
  0,0 0,0 0,0 0,0 71680,0 18432,0 45056,0 20285,1 29872,0 27952,4 4864,0 4671,6 23 0,089 2 0,063 2 0,002 0,153
  0,0 2048,0 0,0 2048,0 69632,0 28672,0 45056,0 18608,1 30128,0 28030,4 4864,0 4672,4 32 0,093 2 0,063 2 0,002 0,158
  ...

在上面这个示例中,jstat每隔1s便会打印垃圾回收的信息,并且不断重复下去。S0CS0U始终为0,而且另一个Survivor区的容量(S1C)可能会下降至0。这是因为,当使用G1 GC时,Java虚拟机不再设置Eden区、Survivor区,老年代区的内存边界,而是将堆划分为若干个等长内存区域。每个内存区域都可以作为Eden区、Survivor区以及老年代区中的任一种,并且可以在不同区域类型之间来回切换。

换句话说,逻辑上只有一个Survivor区。当需要迁移Survivor区中的数据时(即Copying GC),只需另外申请一个或多个内存区域,作为新的Survivor区。因此,Java虚拟机决定在使用G1 GC时,将所有Survivor内存区域的总容量以及已使用量存放至S1C和S1U中,而S0C和S0U则被设置为0。

当发生垃圾回收时,Java虚拟机可能出现Survivor内存区域内的对象被回收或晋升的现象。在这种情况下,Java虚拟机会将这块内存区域回收,并标记为可分配的状态。这样子做的结果是,堆中可能完全没有Survivor内存区域,因而相应的S1C和S1U将会是0。

jstat还有一个非常有用的参数-t,它将在每行数据之前打印目标Java进程的启动时间。例如,在下面这个示例中,第一列代表该Java进程已经启动了10.7秒。

  $ jstat -gc -t 22407
  Timestamp S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT CGC CGCT GCT
  10,7 0,0 0,0 0,0 0,0 55296,0 45056,0 34816,0 20267,8 30128,0 27975,3 4864,0 4671,6 33 0,086 3 0,111 2 0,001 0,198

表中CGC和CGCT,它们分别代表并发GC Stop-The-World的次数和时间。可以比较Java进程的启动时间以及总GC时间(GCT列),或者两次测量的间隔时间以及总GC时间的增量,来得出GC时间占运行时间的比例。如果该比例超过20%,则说明目前堆的压力较大;如果该比例超过90%,则说明堆里几乎没有可用空间,随时都可能抛出OOM异常。

jstat还可以用来判断是否出现内存泄漏。在长时间运行的Java程序中,可以运行jstat命令连续获取多行性能数据,并取这几行数据中OU列(即已占用的老年代内存)的最小值。然后,我们每隔一段较长的时间重复一次上述操作,来获得多组OU最小值。如果这些值呈上涨趋势,则说明该Java程序的老年代内存已使用量在不断上涨,这意味着无法回收的对象在不断增加,因此很有可能存在内存泄漏。

jmap

jmap同样包括多条子命令。

  1. -clstats,该子命令将打印被加载类的信息。
  2. -finalizerinfo,该子命令将打印所有待finalize的对象。
  3. -histo,该子命令将统计各个类的实例数目以及占用内存,并按照内存使用量从多至少的顺序排列。此外,-histo:live只统计堆中的存活对象。
  4. -dump,该子命令将导出Java虚拟机堆的快照。同样,-dump:live只保存堆中的存活对象。

通常会利用jmap -dump:live,format=b,file=filename.bin命令,将堆中所有存活对象导出至一个文件之中。

这里format=b将使jmap导出与-XX:+HeapDumpAfterFullGC-XX:+HeapDumpOnOutOfMemoryError格式一致的文件。这种格式的文件可以被其他GUI工具查看。

由于jmap将访问堆中的所有对象,为了保证在此过程中不被应用线程干扰,jmap需要借助安全点机制,让所有线程停留在不改变堆中数据的状态。也就是说,由jmap导出的堆快照必定是安全点位置的。这可能导致基于该堆快照的分析结果存在偏差。举个例子,假设在编译生成的机器码中,某些对象的生命周期在两个安全点之间,那么:live选项将无法探知到这些对象。

另外,如果某个线程长时间无法跑到安全点,jmap将一直等下去。而jstat不同。这是因为垃圾回收器会主动将jstat所需要的摘要数据保存至固定位置之中,而jstat只需直接读取即可。

jmap(以及接下来的jinfojstackjcmd)依赖于Java虚拟机的Attach API,因此只能监控本地Java进程。

一旦开启Java虚拟机参数DisableAttachMechanism(即使用参数-XX:+DisableAttachMechanism),基于Attach API的命令将无法执行。反过来说,如果不想被其他进程监控,那么需要开启该参数。

jinfo

jinfo命令可用来查看目标Java进程的参数,如传递给Java虚拟机的-X(即输出中的jvm_args)、-XX参数(即输出中的VM Flags),以及可在Java层面通过System.getProperty获取的-D参数(即输出中的System Properties)。

jinfo还可以用来修改目标Java进程的“manageable”虚拟机参数。

举个例子,可以使用jinfo -flag +HeapDumpAfterFullGC <PID>命令,开启<PID>所指定的Java进程的HeapDumpAfterFullGC参数。

可以通过下述命令查看其他"manageable"虚拟机参数:

  $ java -XX:+PrintFlagsFinal -version | grep manageable
  intx CMSAbortablePrecleanWaitMillis = 100 {manageable} {default}
  intx CMSTriggerInterval = -1 {manageable} {default}
  intx CMSWaitDuration = 2000 {manageable} {default}
  bool HeapDumpAfterFullGC = false {manageable} {default}
  bool HeapDumpBeforeFullGC = false {manageable} {default}
  bool HeapDumpOnOutOfMemoryError = false {manageable} {default}
  ccstr HeapDumpPath = {manageable} {default}
  uintx MaxHeapFreeRatio = 70 {manageable} {default}
  uintx MinHeapFreeRatio = 40 {manageable} {default}
  bool PrintClassHistogram = false {manageable} {default}
  bool PrintConcurrentLocks = false {manageable} {default}
  java version "11" 2018-09-25
  Java(TM) SE Runtime Environment 18.9 (build 11+28)
  Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11+28, mixed mode)

jstack

jstack命令可以用来打印目标Java进程中各个线程的栈轨迹,以及这些线程所持有的锁。jstack的其中一个应用场景便是死锁检测。jstack不仅会打印线程的栈轨迹、线程状态(BLOCKED)、持有的锁(locked …)以及正在请求的锁(waiting to lock …),而且还会分析出具体的死锁。

总结

  1. jps将打印所有正在运行的Java进程。

  2. jstat允许用户查看目标Java进程的类加载、即时编译以及垃圾回收相关的信息。它常用于检测垃圾回收问题以及内存泄漏问题。

  3. jmap允许用户统计目标Java进程的堆中存放的Java对象,并将它们导出成二进制文件。

  4. jinfo将打印目标Java进程的配置参数,并能够改动其中manageabe的参数。

  5. jstack将打印目标Java进程中各个线程的栈轨迹、线程状态、锁状况等信息。它还将自动检测死锁。

与[转帖]JVM监控和诊断工具相似的内容:

[转帖]JVM监控和诊断工具

目录 jps jstat jmap jinfo jstack 总结 作者:@dwtfukgv本文为作者原创,转载请注明出处:https://www.cnblogs.com/dwtfukgv/p/15126148.html JVM监控和诊断工具 jps 它将打印所有正在运行的Java进程的相关信息。

[转帖]JVM监控及诊断工具-命令行

https://www.cnblogs.com/xiaojiesir/p/15622372.html 性能指标 停顿时间(响应时间) 提交请求和返回响应之间使用的时间,一般比较关注平均响应时间 常用操作的响应时间列表: 操作 响应时间 打开一个站点 几秒 数据库查询一条记录(有索引) 十几毫秒 机械

[转帖]JVM性能调优监控工具

原文 https://www.cnblogs.com/haiyang1985/p/7654654.html 摘要: JDK自己提供了不少方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps、jstack、jmap、jhat、jstat、hprof等小巧的工具,本

[转帖]jconsole远程监控认证,java远程监控,jmx监控应用,jmx ssl配置,jconsole ssl连接远程应用

知识普及 jmx JMX(java Management Extensions)是一个Java平台的管理和监控接口。任何程序,只要按JMX规范访问这个接口,就可以获取所有管理与监控信息,jconsole与Java VisualVM等常见监测工具都是基于jmx,JMX不但可以用于管理JVM,还可以管理

[转帖]给你的SpringBoot做埋点监控--JVM应用度量框架Micrometer

https://www.cnblogs.com/yunlongn/p/11343848.html 这世上有三样东西是别人抢不走的:一是吃进胃里的食物,二是藏在心中的梦想,三是读进大脑的书 JVM应用度量框架Micrometer实战 前提 spring-actuator做度量统计收集,使用Promet

[转帖]高并发场景下JVM调优实践之路

https://www.jianshu.com/p/f5f5f99e2417 一、背景 2021年2月,收到反馈,视频APP某核心接口高峰期响应慢,影响用户体验。 通过监控发现,接口响应慢主要是P99耗时高引起的,怀疑与该服务的GC有关,该服务典型的一个实例GC表现如下图: image image

[转帖]JVM调优常用命令(jstat、jmap、jstack)

原文:https://www.cnblogs.com/ityouknow/p/5714703.html 一、jstat jstat(JVM statistics Monitoring)是用于监视虚拟机运行时状态信息的命令,它可以显示出虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。 命令

[转帖]【JVM】关于 JVM,你需要掌握这些 | 一文彻底吃透 JVM 系列

【JVM】关于 JVM,你需要掌握这些 | 一文彻底吃透 JVM 系列 作者:冰河 2022-11-04 四川 本文字数:13519 字 阅读完需:约 44 分钟 写在前面 最近,一直有小伙伴让我整理下关于 JVM 的知识,经过十几天的收集与整理,初版算是整理出来了。希望对大家有所帮助。 JDK 是

[转帖]JVM metaspace outofmemory

https://www.jianshu.com/p/1ca44f94e42f 解决服务器进程退出问题(metaspace溢出) 现象 策划反应服务器进不去,远程看了一下进程消失了(crash) 有时候也会出现能登录,但是无法执行操作(进程还在),无法被正常shutdown 进程根目录下出现了java

[转帖]JVM内存非典型术语介绍(shallow/retained/rss/reserved/committed)

https://www.jianshu.com/p/871d6bb3a32d JVM内存非典型术语介绍(shallow/retained/rss/reserved/committed) 背景 ​ 在服务器性能优化内存这一项时,有一些现象很诡异。如top显示的RES很大,但是实际jvm堆内存占用很小,