动手实验:使用 jstat 摸清线上系统的JVM运行状况

2023-10-26

添加VX:ruyuan0220,回复:CSDN,领取更多精品学习资料!

目录

功能强大的jstat

jstat -gc PID

其他的jstat命令

到底该如何使用jstat工具?

新生代对象增长的速率

Young GC的触发频率和每次耗时

每次Young GC后有多少对象是存活和进入老年代

Full GC的触发时机和耗时

本文总结

今日思考题


功能强大的jstat

平时我们对运行中的系统,如果要检查他的JVM的整体运行情况,比较实用的工具之一,就是jstat

他可以轻易的让你看到当前运行中的系统,他的JVM内的Eden、Survivor、老年代的内存使用情况,还有Young GC和Full gC的执行次数以及耗时。

通过这些指标,我们可以轻松的分析出当前系统的运行情况,判断当前系统的内存使用压力以及GC压力,还有就是内存分配是否合理。下面我们就一点点来看看这个jstat工具的使用。

jstat -gc PID

首先第一个命令,就是在你们的生产机器linux上,找出你们的Java进程的PID,这个大家自行百度一下即可,用jps命令就可以看到。

接着就针对我们的Java进程执行:jstat -gc PID。这就可以看到这个Java进程(其实本质就是一个JVM)的内存和GC情况了。

运行这个命令之后会看到如下列,给大家解释一下:

  1. S0C:这是From Survivor区的大小
  2. S1C:这是To Survivor区的大小
  3. S0U:这是From Survivor区当前使用的内存大小
  4. S1U:这是To Survivor区当前使用的内存大小
  5. EC:这是Eden区的大小
  6. EU:这是Eden区当前使用的内存大小
  7. OC:这是老年代的大小
  8. OU:这是老年代当前使用的内存大小
  9. MC:这是方法区(永久代、元数据区)的大小
  10. MU:这是方法区(永久代、元数据区)的当前使用的内存大小
  11. YGC:这是系统运行迄今为止的Young GC次数
  12. YGCT:这是Young GC的耗时
  13. FGC:这是系统运行迄今为止的Full GC次数
  14. FGCT:这是Full GC的耗时
  15. GCT:这是所有GC的总耗时

不知道大家发现什么没有,其实这些指标都是非常实用的jvm gc分析指标,接下来我们一步一步告诉大家该怎么使用这个工具。

另外给大家说句题外话,接下来我们有两篇文章会给大家一段模拟出生产案例的程序,然后在windows本地电脑上运行,然后我们会带着大家用jstat工具去分析他的jvm运行情况。

但是jstat工具本身如果要在windows上运行需要使用专门针对windows的版本,所以后面的文章我们会教会大家怎么在windows上使用jstat工具的。

其他的jstat命令

除了上面的jstat -gc命令是最常用的以外,他还有一些命令可以看到更多详细的信息,如下所示:

  1. jstat -gccapacity PID:堆内存分析
  2. jstat -gcnew PID:年轻代GC分析,这里的TT和MTT可以看到对象在年轻代存活的年龄和存活的最大年龄
  3. jstat -gcnewcapacity PID:年轻代内存分析
  4. jstat -gcold PID:老年代GC分析
  5. jstat -gcoldcapacity PID:老年代内存分析
  6. jstat -gcmetacapacity PID:元数据区内存分析

大家可以后面自己有机会尝试尝试这些命令,多看看,还是挺好玩儿的,但是其实最完整、最常用、最实用的还是jstat -gc命令,基本足够我们日常分析jvm的运行情况了。

到底该如何使用jstat工具?

接着教教大家一些jstat工具使用的小技巧,先明确一下,我们分析线上的JVM进程,最想要知道的信息有哪些?

包括如下:新生代对象增长的速率,Young GC的触发频率,Young GC的耗时,每次Young GC后有多少对象是存活下来的,每次Young GC过后有多少对象进入了老年代,老年代对象增长的速率,Full GC的触发频率,Full GC的耗时。

只要知道了这些信息,其实我们就可以结合之前几周的文章分析过的JVMGC优化的方法,合理分配内存空间,尽可能让对象留在年轻代不进入老年代,避免发生频繁的Full GC。这就是对JVM最好的性能优化了!

因此我们一点点分析,通过jstat工具如何得到上述信息。

新生代对象增长的速率

如果认真看过之前几周文章的同学,应该都知道,我们平时对jvm第一个要了解的事儿,就是随着系统运行,每秒钟会在年轻代的Eden区分配多少对象。

要分析这东西,你只要在线上linux机器上运行如下命令:jstat -gc PID 1000 10

这行命令,他的意思就是每隔1秒钟更新出来最新的一行jstat统计信息,一共执行10次jstat统计

通过这个命令,你可以非常灵活的对线上机器通过固定频率输出统计信息,观察每隔一段时间的jvm中的Eden区对象占用变化。

比如给大家举个例子,执行这个命令之后,第一秒先显示出来Eden区使用了200MB内存,第二秒显示出来的那行统计信息里,发信Eden区使用了205MB内存,第三秒显示出来的那行统计信息里,发现Eden区使用了209MB内存,以此类推。

此时你可以轻易的推断出来,这个系统大概每秒钟会新增5MB左右的对象。

而且这里大家可以根据自己系统的情况灵活多变的使用,比如你们系统负载很低,不一定每秒都有请求,那么可以把上面的1秒钟调整为1分钟,甚至10分钟,去看你们系统每隔1分钟或者10分钟大概增长多少对象。

还有就是一般系统都有高峰和日常两种状态,比如系统高峰期用的人很多,此时你就应该在系统高峰期去用上述命令看看高峰期的对象增长速率。然后你再得在非高峰的日常时间段内看看对象的增长速率。

按照上述思路,基本上你可以对线上系统的高峰和日常两个时间段内的对象增长速率有很清晰的了解。

Young GC的触发频率和每次耗时

接着下一步我们就想知道大概多久会触发一次Young GC,以及每次Young GC的耗时了。

其实多久触发一次Young GC就很容易推测出来了,因为系统高峰和日常时候的对象增长速率你都知道了,那么非常简单就可以推测出来高峰期多久发生一次Young GC,日常期多久发生一次Young GC。

比如你Eden区有800MB内存,那么发现高峰期每秒新增5MB对象,大概高峰期就是3分钟会触发一次Young GC。日常期每秒新增0.5MB对象,那么日常期大概需要半个小时才会触发一次Young GC。

那么每次Young GC的平均耗时呢?

简单,之前给大家说过,jstat会告诉你迄今为止系统已经发生了多少次Young GC以及这些Young GC的总耗时。

比如系统运行24小时后共发生了260次Young GC,总耗时为20s。那么平均下来每次Young GC大概就耗时几十毫秒的时间。

你大概就知道每次Young GC的时候会导致系统停顿几十毫秒。

每次Young GC后有多少对象是存活和进入老年代

接着我们想要知道,每次Young GC后有多少对象会存活下来,以及有多少对象会进入老年代。

其实每次Young GC过后有多少对象会存活下来,这个没法直接看出来,但是有办法可以大致推测出来。

之前我们已经推算出来高峰期的时候多久发生一次Young GC,比如3分钟会有一次Young GC

那么此时我们可以执行下述jstat命令:jstat -gc PID 180000 10。这就相当于是让他每隔三分钟执行一次统计,连续执行10次。

此时大家可以观察一下,每隔三分钟之后发生了一次Young GC,此时Eden、Survivor、老年代的对象变化。

正常来说,Eden区肯定会在几乎放满之后重新变得里面对象很少,比如800MB的空间就使用了几十MB。Survivor区肯定会放入一些存活对象,老年代可能会增长一些对象占用。所以这里的关键,就是观察老年代的对象增长速率。

从一个正常的角度来看,老年代的对象是不太可能不停的快速增长的,因为普通的系统其实没那么多长期存活的对象。如果你发现比如每次Young GC过后,老年代对象都要增长几十MB,那很有可能就是你一次Young GC过后存活对象太多了。

存活对象太多,可能导致放入Survivor区域之后触发了动态年龄判定规则进入老年代,也可能是Survivor区域放不下了,所以大部分存活对象进入老年代。

最常见的就是这种情况。如果你的老年代每次在Young GC过后就新增几百KB,或者几MB的对象,这个还算情有可缘,但是如果老年代对象快速增长,那一定是不正常的。

所以通过上述观察策略,你就可以知道每次Young GC过后多少对象是存活的,实际上Survivor区域里的和进入老年代的对象,都是存活的。

你也可以知道老年代对象的增长速率,比如每隔3分钟一次Young GC,每次会有50MB对象进入老年代,这就是年代对象的增长速率,每隔3分钟增长50MB。

Full GC的触发时机和耗时

只要知道了老年代对象的增长速率,那么Full GC的触发时机就很清晰了,比如老年代总共有800MB的内存,每隔3分钟新增50MB对象,那么大概每小时就会触发一次Full GC。

然后可以看到jstat打印出来的系统运行起劲为止的Full GC次数以及总耗时,比如一共执行了10次Full GC,共耗时30s,每次Full GC大概就是需要耗费3s左右。

本文总结

通过本文对jstat命令的介绍,以及结合我们之前学习过的jvm运行原理,我们教给了大家这套分析线上系统jvm运行情况的技巧

大家完全可以灵活运行jstat这个实用的工具,轻而易举的掌控到线上jvm运行的详细情况,然后针对jvm的具体运行情况去进行有针对性的优化。

另外,很多同学会问了:老师,其实有很多其他的工具也特别好用啊,比如JConsole、VisualVM等可视化的监控工具,还有其他一些开源的监控系统,都是可视化的。

针对这个问题,其实我也没说不可以用那些可视化工具,下篇文章我们就要给大家介绍更多的可视化监控JVM的工具。

但是有一点要告诉大家,一个优秀、合格的工程师,他一定是可以非常灵活的运用各种命令行工具,在命令行就搞定一切的。

所以jstat作为一个最简单易用、高效实用的命令行jvm监控工具,其实绝对是值得大家首先掌握他的。因为每个人的公司情况不一样,万一你公司不支持你用各种可视化工具呢?那你就必须从最“low”最原始的命令行工具开始,快速上手实用,定位问题。

而且其实你理解了本文的思想之后,你用其他任何工具,都能轻松的把线上jvm的运行情况通过工具提供的数据分析清楚。

思考题

在自己线上负责的系统使用jstat命令,按照上述我们介绍的思路,把以下jvm运行情况全部摸出来:

  1. 新生代对象增长的速率
  2. Young GC的触发频率
  3. Young GC的耗时
  4. 每次Young GC后有多少对象是存活下来的
  5. 每次Young GC过后有多少对象进入了老年代
  6. 老年代对象增长的速率
  7. Full GC的触发频率
  8. Full GC的耗时

如果有分析心得的,可以发评论区里,跟其他小伙伴一起分享,如果在落地过程中遇到任何问题,也欢迎大家在评论区踊跃发言提问。

----------------------- END -----------------------

添加VX:ruyuan0220 或扫描下方二维码,回复:CSDN,领取更多精品学习资料!

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动手实验:使用 jstat 摸清线上系统的JVM运行状况 的相关文章

  • 如何使用双括号初始化 Map of Map

    我确实明白双括号初始化有其自己的隐藏成本 仍然有可能的初始化方法Map
  • 64位CLR可以使用压缩指针吗?

    我读过一些关于一些 64 位 Java VM 实现中的压缩对象指针的内容 据我了解 其原理是将引用存储为从一个对象到另一个对象的相对 32 位地址偏移量 而不是完整的 64 位指针 以获取内存 我认为这种优化目前还没有应用于 NET CLR
  • 如果小程序在浏览器的 JRE 中运行,为什么机器上还需要 JRE?

    Applet 在浏览器的 JRE 中运行 这是否意味着您不必在计算机上安装 JRE 即可运行小程序 浏览器的 JVM is您计算机上安装的 JRE 浏览器通常不会附带自己的浏览器 它们只是使用您系统上已安装的任何浏览器 也许您混淆了 Jav
  • 空闲后 JVM JIT 去优化

    我使用Java主要是为了编写宠物项目 这些项目大部分时间都是闲置的 闲置数小时 天后 响应时间增加到秒 最多 10 秒 然后慢慢减少到 200 300 毫秒 据我了解 发生这种情况是因为 JIT去优化 https www safariboo
  • 如何在 Windows 中查看正在执行的 java 程序的类路径和 jvm 参数

    在 nix 我只是这样做ps ef grep java查看正在执行的 java 程序的 jvm 参数和类路径 如何在 Windows 命令提示符中看到它 我想看看某些 jar 是否实际上位于正在运行的 weblogic 服务器的类路径中 从
  • Java中的线程何时从内存中删除? [复制]

    这个问题在这里已经有答案了 来自 Java API 文档 Java虚拟机继续执行线程 直到遵循 发生 所有非守护线程的线程都已死亡 或者通过返回 从调用 run 方法或抛出异常 传播到 run 方法之外 我希望我的假设是正确的 一旦线程完成
  • 有保证的方法可以在运行时获取成员字段的源顺序吗?

    我正在寻找一种按源顺序检索 在运行时 类的字段的方法 以便我可以执行自己的 初始化处理 该处理基于声明的顺序 我知道 Javadoc 用于Class getDeclaredFields 明确指出不保证订单 SO 上的一些答案指向Javass
  • Java 系统属性的范围

    在Java中我们使用System setProperty 方法来设置一些系统属性 根据本文 http blogs oracle com foo entry monitored system setproperty系统属性的使用有点棘手 Sy
  • Android Studio 构建 gradle OutOfMemoryError

    我是安卓新手 我在 Android studio 中导入 Github 项目 但我看到这个问题 Error java lang OutOfMemoryError Java heap space 错误 java lang OutOfMemor
  • 强制小程序加载到同一个 JVM 实例中?

    我接管了一个旧 Web 应用程序的维护工作 该应用程序使用嵌入在同一网页中的多个小程序 这曾经工作得很好 但自从引入了下一代 Java 插件 1 6 0 10 后 不保证各个小程序能够加载到同一个 JVM 实例中 如果它们加载在不同的 JV
  • 为什么我的网络浏览器版本的 java 与命令行版本不同

    the Safari browser says I am running 7 But the command line says I am running 6 prg ceylon dist samples helloworld java
  • 为什么要实现finalize()?

    我已经阅读了很多 Java 新手问题finalize 令人困惑的是 没有人真正明确表示 Finalize 是一种不可靠的清理资源的方法 我看到有人评论说他们用它来清理连接 这真的很可怕 因为接近保证连接关闭的唯一方法是最后实现 try ca
  • Cassandra DB 中的日期插入:重要的 1 小时轮班问题(后续)

    这是这个的后续其他原帖 https stackoverflow com questions 23080188 date insertion in cassandra db non trivial 1h shift issue 2308355
  • getResourceAsStream(file) 在哪里搜索文件?

    我很困惑getResourceAsStream 我的包结构如下 src net floodlightcontroller invoked getResourceAsStream here resources floodlightdefaul
  • 显示JVM中当前运行的所有线程组和线程

    所以我的任务是显示所有线程组以及当前在 JVM 中运行的属于这些组的所有线程 输出时应首先显示线程组 然后在下面显示该组中的所有线程 这是针对所有线程组完成的 目前 我的代码将仅显示每个线程组 然后显示每个线程 但我不确定如何达到我所描述的
  • Java 堆被无法访问的对象淹没

    我们的 Java EE 应用程序开始出现一些严重问题 具体来说 应用程序在启动后几分钟内就运行了高达 99 的老年代堆 不会抛出 OOM 但实际上 JVM 没有响应 jstat 显示老年代的大小根本没有减少 没有垃圾收集正在进行 并且kil
  • 哪种语言(在 JVM 上运行)最适合创建 DSL?

    我们需要创建复杂的固定长度和可变长度字符串 这些字符串可能代表客户资料 订单等 你们建议使用哪种基于 JVM 的编程语言 想法是让最终用户使用此 DSL 创建字符串 所以我正在寻找验证 代码完成等 Groovy http docs code
  • 我的代码中出现内存不足异常

    作为 Oracle 数据库压力测试的一部分 我正在长时间运行代码并使用 java 版本 1 4 2 简而言之 我正在做的是 while true Allocating some memory as a blob byte data new
  • 为什么 JVM 同时具有“invokespecial”和“invokestatic”操作码?

    两条指令都使用静态而不是动态调度 似乎唯一的实质性区别是invokespecial始终将一个对象作为其第一个参数 该对象是分派方法所属类的实例 然而 invokespecial实际上并没有把物体放在那里 编译器负责通过在发出之前发出适当的堆
  • STS 无法在我的计算机上启动

    我试图在 eclipse 上设置 Spring mvc 项目 基本项目进展顺利 但是使用 Restful 服务 Jersey 等开始出现许多与依赖项相关的错误 所以我打算转到STS 我正在使用 STS 2 9 2 它给我 无法创建java虚

随机推荐

  • MFC的静态库.lib、动态库.dll(包含引入库.lib)以及Unicode库示例

    以vs2012为标准 转自 http technet microsoft com zh cn library w4zd66ye 有改动 一 MFC的静态库 lib MFC静态库使用下列命名约定 uAFXcWd LIB 库命名约定的说明符如下
  • VOSviewer 操作指南 简明

    VOSviewer 操作指南 Vosviewer 软件是一种知识图谱可视化软件 并且可以使用基本的分类聚类方法 帮助我们得到进一步的信息 下载地址 https www vosviewer com download 解压完成后 你得到因该是一
  • 27 个为什么,帮助你更好的理解Python

    选自 Python官方文档 https docs python org zh cn 3 7 faq design html
  • pytorch报错:RuntimeError: CUDA error: device-side assert triggered究极解决方案

    原因 模型的数据处理出了问题 一般是类似于数组访问越界的问题 1 例如分类的标签是数据处理的时候是1 10 但是torch在计算交叉熵是默认是0 9 2 embedding模块的词表长度问题 比如embedding中词表总长度是100 但是
  • Unix时间与Win32 FileTime时间

    Unix 时间 1970 01 01 00 00 00 与 Win32 FileTime 时间 1601 01 01 00 00 00 两者相差毫秒数为 11644473600000L Win32 FileTime 采用 100ns 为单位
  • Postgres安装

    准备工作 1 查看自己的电脑是多少位 cmd界面中输入 systeminfo 按回车 主要是看一下系统类型 系统类型 64 位操作系统 基于 x64 的处理器 版本 Windows 10 专业版 版本号 20H2 安装日期 2021 10
  • 【IDEA】idea 调试技巧 查看字段 什么时候修改的

    文章目录 1 概述 1 概述 如果你阅读源码 你一定会有个困扰 类中的某个字段的值到底是在哪里改变的 你要一点点追踪调用栈 逐步排查 稍不留神 就可能有遗漏 我们可以在 IntelliJ IDEA 中为某个字段添加断点 当字段值有修改时 自
  • es--基础--06--es集群

    es 基础 06 es集群 1 集群概念 概念看es入门学习3 理论 2 集群的搭建 利用原有的单机 elasticsearch 5 6 8 来搭建 搭建三台es服务器 分别提供的端口是9201 9202 9203 2 1 停止elasti
  • 特征选择策略:为检测乳腺癌生物标志物寻找新出口

    内容一览 microRNA 小分子核糖核酸 是一类短小的单链非编码 RNA 转录体 这些分子在多种恶性肿瘤中呈现失控性生长 因此近年来被诸多研究确定为确诊癌症的可靠的生物标志物 biomarker 在多种病理分析中 差异表达分析 Diffe
  • 解决Dropbox国内无法实时更新的问题

    Dropbox软件需要在全局模式下才能时时同步 但全局模式下无法打开某些国内网站 所以需要解决该问题 解决方法 通过设置代理的方式让Dropbox软件自动同步 但在尝试中 设置为socks5代理发现不能使用 改为http代理 马上生效 打开
  • 十分钟带你走进Hive世界(每走一步都是为了离你更近些)

    该文章已更新到语雀中 后台回复 语雀 可获取进击吧大数据整个职业生涯持续更新的所有资料 该文基于Hive专题 从SQL聊Hive底层执行原理进一步的深入学习Hive 相信大多数童鞋对于Hive底层的执行流程只是局限于理论层面 那么本篇将带大
  • Windows平台Unity3d下如何同时播放多路RTSP或RTMP流

    好多开发者在做AR VR或者教育类产品时 苦于如何在windows平台构建一个稳定且低延迟的RTSP或者RTMP播放器 如果基于Unity3d完全重新开发一个播放器 代价大 而且周期长 不适合快速出产品 我们认为当前最好的方式就是集成现有N
  • 【计算机网络】 TCP——四次挥手

    文章目录 流程 考点 流程 主动方打算关闭连接 此时会发送一个TCP首部FIN标志位被置为1的报文 也即FIN报文 之后主动方进入FIN WAIT 1状态 被动方收到该报文后 就向主动方发送ACK应答报文 接着被动方进入CLOSE WAIT
  • Qt 6.4.2在Windows上安装过程及简单验证

    Qt是一个跨平台的C 开发库 用来开发图形用户界面 Graphical User Interface GUI 它支持Windows Linux macOS Android iOS QNX等平台 一个框架 一套代码库 任意平台部署 Qt有开源
  • Centos 8上安装Docker配置国内镜像源

    一 使用背景 在阿里云上安装docker后 如果采用国外的源地址 pull的时候 速度慢到让人崩溃 二 国内常用加速地址 Docker中国官方加速地址 https registry docker cn com 网易163镜像加速 http
  • 使用 Waffle 进行测试的基本流程及使用方法-文章来自问我社区

    前言 Waffle 是一款适配 ehter js 的智能合约测试库 本样例演示了使用 Waffle 进行测试的基本流程及使用方法 Waffle 详细使用方法可以参考 Waffle 官网 对于不熟悉 Waffle 测试框架的开发者 可以根据本
  • 腾讯Cos对象储存api用法教程中英图文讲解

    Chinar blog www chinar xin 腾讯云 Cos api sdk详解 本文提供全流程 中文翻译 Chinar 的初衷是将一种简单的生活方式带给世人 使有限时间 具备无限可能 Chinar 心分享 心创新 助力快速理解 C
  • Egg简介

    Egg 前言 Egg js 为企业级框架和应用而生 基于Koa开发封装 性能优异 内置多进程管理 具有高扩展性 且提供了基于Egg定制上层框架的能力 帮助开发团队降低了开发维护成本 约定先于配置 相较于express更加灵活可配 Koa K
  • gateway网关的使用

    今天与大家分享gateway网关的使用 1 gateway简介 1 1 是什么 SpringCloud Gateway 作为 Spring Cloud 生态系统中的网关 目标是替代 Zuul 在Spring Cloud 2 0以上版本中 没
  • 动手实验:使用 jstat 摸清线上系统的JVM运行状况

    添加VX ruyuan0220 回复 CSDN 领取更多精品学习资料 目录 功能强大的jstat jstat gc PID 其他的jstat命令 到底该如何使用jstat工具 新生代对象增长的速率 Young GC的触发频率和每次耗时 每次