Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >JDK中常用于监控及诊断工具有哪些?

JDK中常用于监控及诊断工具有哪些?

原创
作者头像
码农架构
修改于 2021-02-26 10:05:16
修改于 2021-02-26 10:05:16
1.1K0
举报
文章被收录于专栏:码农架构码农架构

原文地址:JDK中常用于监控及诊断工具有哪些?

jps

你可能用过ps命令,打印所有正在运行的进程的相关信息。JDK 中的jps命令。沿用了同样的概念:它将打印所有正在运行的 Java 进程的相关信息

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

(如-XX:+UnlockExperimentalVMOptions -XX:+UseZGC);-m将打印传递给主类的参数。

具体的示例如下所示

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

当获得 Java 进程的进程 ID 之后,我们便可以调用接下来介绍的各项监控及诊断工具了。

jstat

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

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

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

当监控本地环境的 Java 进程时,VMID 可以简单理解为 PID。如果需要监控远程环境的 Java 进程,你可以参考 jstat 的帮助文档。

在上面这个示例中,22126 进程是一个使用了 CMS 垃圾回收器的 Java 进程。我们利用jstat的-gc子命令,来打印该进程垃圾回收相关的数据。命令最后的1s 4表示每隔 1 秒打印一次,共打印 4 次。

在-gc子命令的输出中,前四列分别为两个 Survivor 区的容量(Capacity)和已使用量(Utility)。我们可以看到,这两个 Survivor 区的容量相等,而且始终有一个 Survivor 区的内存使用量为 0。

当使用默认的 G1 GC 时,输出结果则有另一些特征:

在上面这个示例中,jstat每隔 1s 便会打印垃圾回收的信息,并且不断重复下去。

你可能已经留意到,S0C和S0U始终为 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 秒。

我们可以比较 Java 进程的启动时间以及总 GC 时间(GCT 列),或者两次测量的间隔时间以及总 GC 时间的增量,来得出 GC 时间占运行时间的比例。

如果该比例超过 20%,则说明目前堆的压力较大;如果该比例超过 90%,则说明堆里几乎没有可用空间,随时都可能抛出 OOM 异常。

jstat还可以用来判断是否出现内存泄漏。在长时间运行的 Java 程序中,我们可以运行jstat命令连续获取多行性能数据,并取这几行数据中 OU 列(即已占用的老年代内存)的最小值。

然后,我们每隔一段较长的时间重复一次上述操作,来获得多组 OU 最小值。如果这些值呈上涨趋势,则说明该 Java 程序的老年代内存已使用量在不断上涨,这意味着无法回收的对象在不断增加,因此很有可能存在内存泄漏。

上面没有涉及的列(或者其他子命令的输出),你可以查阅帮助文档了解具体含义。至于文档中漏掉的 CGC 和 CGCT,它们分别代表并发 GC Stop-The-World 的次数和时间。

jmap

在这种情况下,我们便可以请jmap命令(帮助文档)出马,分析 Java 虚拟机堆中的对象。

jmap同样包括多条子命令。

  • -clstats,该子命令将打印被加载类的信息。
  • -finalizerinfo,该子命令将打印所有待 finalize 的对象。
  • -histo,该子命令将统计各个类的实例数目以及占用内存,并按照内存使用量从多至少的顺序排列。此外,-histo:live只统计堆中的存活对象。
  • -dump,该子命令将导出 Java 虚拟机堆的快照。同样,-dump:live只保存堆中的存活对象。 我们通常会利用jmap -dump:live,format=b,file=filename.bin命令,将堆中所有存活对象导出至一个文件之中。

下面我贴了一段-histo子命令的输出:

由于jmap将访问堆中的所有对象,为了保证在此过程中不被应用线程干扰,jmap需要借助安全点机制,让所有线程停留在不改变堆中数据的状态。

也就是说,**由jmap导出的堆快照必定是安全点位置的。这可能导致基于该堆快照的分析结果存在偏差。**举个例子,假设在编译生成的机器码中,某些对象的生命周期在两个安全点之间,那么:live选项将无法探知到这些对象。

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

关于这种长时间等待的情况,你可以通过下面这段程序来复现:

jmap(以及接下来的jinfo、jstack和jcmd)依赖于 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” 虚拟机参数:

jstack

jstack命令可以用来打印目标 Java 进程中各个线程的栈轨迹,以及这些线程所持有的锁。

jstack的其中一个应用场景便是死锁检测。这里我用jstack获取一个已经死锁了的 Java 程序的栈信息。具体输出如下所示:

我们可以看到,jstack不仅会打印线程的栈轨迹、线程状态(BLOCKED)、持有的锁(locked …)以及正在请求的锁(waiting to lock …),而且还会分析出具体的死锁。

jcmd

你还可以直接使用jcmd命令来替代前面除了jstat之外的所有命令

总结

JDK 中用于监控及诊断的命令行工具。主要有下列几种方式。

  • jps 将打印所有正在运行的 Java 进程。
  • jstat 允许用户查看目标 Java 进程的类加载、即时编译以及垃圾回收相关的信息。它常用于检测垃圾回收问题以及内存泄漏问题。
  • jmap 允许用户统计目标 Java 进程的堆中存放的 Java 对象,并将它们导出成二进制文件。
  • jinfo 将打印目标 Java 进程的配置参数,并能够改动其中 manageabe 的参数。
  • jstack 将打印目标 Java 进程中各个线程的栈轨迹、线程状态、锁状况等信息。它还将自动检测死锁。
  • jcmd 则是一把瑞士军刀,可以用来实现前面除了jstat之外所有命令的功能。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
JVM--监控及诊断工具
你可能用过ps命令,打印所有正在运行的进程的相关信息。JDK 中的jps命令(帮助文档)沿用了同样的概念:它将打印所有正在运行的 Java 进程的相关信息。
终码一生
2022/04/14
7450
JVM--监控及诊断工具
jvm分析工具和查看命令
与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程号。
java思维导图
2019/05/21
1.6K0
jvm系列(四):jvm调优-命令篇
运用jvm自带的命令可以方便的在生产监控和打印堆栈的日志信息帮忙我们来定位问题!虽然jvm调优成熟的工具已经有很多:jconsole、大名鼎鼎的VisualVM,IBM的Memory Analyzer等等,但是在生产环境出现问题的时候,一方面工具的使用会有所限制,另一方面喜欢装X的我们,总喜欢在出现问题的时候在终端输入一些命令来解决。所有的工具几乎都是依赖于jdk的接口和底层的这些命令,研究这些命令的使用也让我们更能了解jvm构成和特性。 Sun JDK监控和故障处理命令有jps jstat jmap jh
纯洁的微笑
2018/04/19
1.9K0
jvm系列(四):jvm调优-命令篇
性能监控之常见JDK命令行工具整理
格式:-XX:[+-]表示启用或者禁用name属性比如:-XX:+UseConcMarkSweepGC 启用CMS垃圾回收器 -XX:+UseG1GC 启用G1垃圾回收器
高楼Zee
2019/07/17
9730
性能监控之常见JDK命令行工具整理
jvm内存分配及对象创建和回收过程
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
suveng
2019/09/17
8890
jvm内存分配及对象创建和回收过程
使用JDK自带工具进行JVM内存分析之旅
本文将通过一次jvm内存分析过程来说明jps、jcmd、jstat、jstack 和 jmap 工具的使用方法。
codetrend
2024/04/19
2.1K0
使用JDK自带工具进行JVM内存分析之旅
十三、JDK的命令行工具
前面的博文我们介绍了一些关于jvm的一些基础知识,本文介绍一些jdk的命令行工具,通过这些工具我们可以对运行日志、异常堆栈、GC日志、线程快照(threaddump/javacore 文件)、堆转储快照(heapdump/hprof 文件)等文件进行分析,从而定位解决问题。 jdk的彬目录中有许多命令行工具,其中java.exe、javac.exe这两个命令行工具是我们最熟悉的。同时,还有其他的许多命令行工具,我们今天介绍的就是这些命令行工具中的一部分。bin目录内容如下图所示。
栋先生
2018/09/29
8250
十三、JDK的命令行工具
再也不怕面试官问性能分析了
有时候碰到服务器CPU飙升或者程序卡死之类的问题,一般都不太好定位。这类bug一般都隐藏的比较深并且还可能是偶发性的,比较棘手。
秃头哥编程
2022/03/30
8500
再也不怕面试官问性能分析了
深入理解java虚拟机学习笔记(三)-虚拟机性能监控与故障处理工具
该命令主要与jmap搭配使用,用来分析jmap转储的转储快照。其中构建了一个微型的http/html服务器。生成dump文件的分析结果后可以通过浏览器进行查看。 通常情况下不采用jhat进行分析,一方面,分析工作需要耗费额外的资源和时间,既然都要在其他机器进行,则不需要限定于上述工具。另外一方面,jhat界面比较简陋,可以用visualVM,eclipse的Memory Analizer 等更加专业的分析工具进行替换。
冬天里的懒猫
2020/08/03
7470
使用 JDK 自带工具进行 JVM 诊断调优实战
最近参加面试多次被面试官问到JVM调 优方面的问题,即时自己面试前也重点复习了这一块的面试题,但是发现还是回答地不太好,浪费了好多次面试机会,真是让自己很抓狂。归根结底是自己以前一直只注重业务,而忽略了JVM调优这一块,对JVM这一块的实践太少了。这几天自己也重点观看了马士兵老师的JVM调优视频课, 看完之后自己也在本机和腾讯云服务器上进行了一番实践,感觉还是很有收获的。
用户3587585
2023/12/18
9290
使用 JDK 自带工具进行  JVM 诊断调优实战
【JVM进阶之路】八:性能监控工具-命令行篇
在实际的故障排查、性能监控中,常常是操作系统的工具和Java虚拟机的工具结合使用。
三分恶
2021/04/09
1.2K0
【JVM进阶之路】八:性能监控工具-命令行篇
面经手册 · 第26篇《JVM故障处理工具,使用总结》
其实最好的方式就是归纳、整理、实践、输出,一套组合拳下来,你就掌握了这个系列的知识了。
小傅哥
2021/01/18
1.3K0
面经手册 · 第26篇《JVM故障处理工具,使用总结》
JVM监控及诊断工具
jstat用法 其中-gc可以换成-class 、-gcnew、-gcold等参数;而54992表示的JVM的进程id(可能通过上面的jps命令查看) ;4s表求每4秒打印一次,后面的3表求共打印三次。 打印的各参数含义如下: 1:S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used) 2:EC、EU:Eden区容量和使用量 3:OC、OU:年老代容量和使用量 4:MC、MU:元数据区容量和使用量 5:CCSC、CCSU:压缩类空间容量和使用量 5:YGC、YGT:年轻代GC次数和GC耗时 6:FGC、FGCT:Full GC次数和Full GC耗时 7:GCT:GC总耗时 jstat可以用来判断系统是否出现了内存泄漏,方法是通过一短长时间的观察OU的增长情况,如果OU稳定增长,则有可能出现内存泄漏。
良辰美景TT
2018/12/10
2.1K0
JVM监控及诊断工具
JVM难学?那是因为你没认真看完这篇文章
JAVA程序运行与虚拟机之上,运行时需要内存空间。虚拟机执行JAVA程序的过程中会把它管理的内存划分为不同的数据区域方便管理。
烂猪皮
2018/08/22
4340
深入理解Java虚拟机-如何利用 JDK 自带的命令行工具监控上百万的高并发的虚拟机性能
在前面的几篇文章已经讲解了利用一些可视化的工具进行 JVM 性能的监控,但是,在服务器上,我们很多时候是没有办法使用可视化的界面进行这种工作的,这种情景就相当于你需要远程的 linux 系统一样,我们没有其他的办法,只有一种办法就是利用命令行进行操控,而当我们将我们的项目部署到远程的服务器上的时候,我们是没有办法利用可视化的工具对 JVM 进行有效的监控的,这个时候 JDK 的自带的工具就是发挥发的作用的时候了。
好好学java
2019/12/20
4960
深入理解Java虚拟机-如何利用 JDK 自带的命令行工具监控上百万的高并发的虚拟机性能
如何使用JVM工具排查线上问题?
今天我们来聊聊如何使用 JVM 工具排查线上问题,在程序运行过程中,我们可能会遇到各种问题,而稳定性风险是我们无法回避的一个话题。由于代码质量不佳或架构设计上的缺陷,JVM 层面的风险主要表现为内存溢出和死锁等问题,常见的异常包括 OOM 和 CPU 使用率急剧上升。为了深入了解问题的根本原因,我们需要熟练掌握 JVM 工具的使用。幸运的是,JVM 已经为我们提供了一系列的诊断工具。今天,我会带你熟悉 JVM 的一些常见诊断工具。
写bug的高哈哈
2025/01/06
1460
如何使用JVM工具排查线上问题?
JVM内存调优工具篇之java自带工具
jdk在安装的时候会提供一些性能分析、故障诊断、JVM监控之类的工具,了解这些工具对我们分析JVM内存、JVM调优有一定的帮助,本篇文章来学习一下。
索码理
2022/12/28
1.1K0
JVM内存调优工具篇之java自带工具
JVM系列第15讲:JDK性能监控命令
jps 命令可以列出所有的 Java 进程。如果 jps 不加任何参数,可以列出 Java 程序的进程 ID 以及 Main 函数短名称,如下所示。
陈树义
2018/12/25
5480
Java开发之jdk命令行工具详解
由于java jdk命令行工具比较重要,加之看到一篇不错的总结,所以接下来详细讲解。
lyb-geek
2018/07/26
9170
Java开发之jdk命令行工具详解
JVM-监控及诊断工具
ps(Java Process Status):显示指定系统内所有的HotSpot虚拟机进程(查看虚拟机进程信息),可用于查询正在运行的虚拟机进程。
才疏学浅的木子
2023/10/17
6380
JVM-监控及诊断工具
相关推荐
JVM--监控及诊断工具
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档