JVM - 要上线了,JVM参数还没正儿八经的估算过咋办?

简介: JVM - 要上线了,JVM参数还没正儿八经的估算过咋办?

20200706234622876.png


Pre


如题, 一顿操作猛如虎,业务系统总算快发布了,可是JVM的参数还是当初随意设置的那么几个参数, 咋弄? 系统的流量预估(均值、峰值)导致一系列的评估: 每秒的对象生成大小,新生代 老年代的比例是否合理, 动态年龄判断机制、老年代担保机制会不会被频繁触发,full gc 的频率。。。。


留下一脸懵逼的你在风中瑟瑟发抖~


不要怕 ,今天我们就来看一下如何通过合理的预估来设置系统的JVM参数

JVM-10虚拟机性能监控与故障处理工具之【JDK的命令行】


image.png


jstat

[root@artisan ~]# java -version
java version "1.8.0_221"
Java(TM) SE Runtime Environment (build 1.8.0_221-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)
[root@artisan ~]# jstat -help
Usage: jstat -help|-options
       jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
Definitions:
  <option>      An option reported by the -options option
  <vmid>        Virtual Machine Identifier. A vmid takes the following form:
                     <lvmid>[@<hostname>[:<port>]]
                Where <lvmid> is the local vm identifier for the target
                Java virtual machine, typically a process id; <hostname> is
                the name of the host running the target Java virtual machine;
                and <port> is the port number for the rmiregistry on the
                target host. See the jvmstat documentation for a more complete
                description of the Virtual Machine Identifier.
  <lines>       Number of samples between header lines.
  <interval>    Sampling interval. The following forms are allowed:
                    <n>["ms"|"s"]
                Where <n> is an integer and the suffix specifies the units as 
                milliseconds("ms") or seconds("s"). The default units are "ms".
  <count>       Number of samples to take before terminating.
  -J<flag>      Pass <flag> directly to the runtime system.
[root@artisan ~]# 


官方都说了 jstat -help|-options ,是吧 看看 options的选项吧

[root@artisan ~]# jstat -options
-class
-compiler
-gc
-gccapacity
-gccause
-gcmetacapacity
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcutil
-printcompilation
[root@artisan ~]# 


从中可以看出 , jstat (JVM Statistics Monitoring Tool)用于监视虚拟机各种运行状态信息的命令行工具。 它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾回收、JIT编译等运行数据 。


划重点, 垃圾回收 ,这里我们重点看GC垃圾回收 ,因为JVM调优的本质就是为了减少full GC 的发生。


通过不同方式的测试,观察GC的情况,可以很好的预测和分析 每秒的对象生成大小,新生代 老年代的比例是否合理, 动态年龄判断机制、老年代担保机制会不会被频繁触发,full gc 的频率。。。。


选项option代表用户希望查询的虚拟机信息,主要分为3类:类装载、垃圾收集、运行期编译状况。


jstat的主要选项


image.png

评估内存使用及GC压力的整体情况 jstat -gc PID

[root@artisan ~]# jps
5811 kooteam.jar
10478 Jps
[root@artisan ~]# jstat -gc 5811 
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
34944.0 34944.0  0.0    0.0   279616.0 44044.5   699072.0   13979.2   21248.0 20630.5 2560.0 2386.8      0    0.000   1      0.338    0.338
[root@artisan ~]# 


参数解读


S0C:第一个幸存区的大小,单位KB

S1C:第二个幸存区的大小

S0U:第一个幸存区的使用大小

S1U:第二个幸存区的使用大小

EC:伊甸园区的大小

EU:伊甸园区的使用大小

OC:老年代大小

OU:老年代使用大小

MC:方法区大小(元空间)

MU:方法区使用大小

CCSC:压缩类空间大小

CCSU:压缩类空间使用大小

YGC:年轻代垃圾回收次数

YGCT:年轻代垃圾回收消耗时间,单位s

FGC:老年代垃圾回收次数

FGCT:老年代垃圾回收消耗时间,单位s

GCT:垃圾回收消耗总时间,单位s


当然了,看一次肯定不行啊,一般都是间隔多长时间输出一次,持续观察。


比如 间隔2秒,打印1万次

[root@artisan ~]# jstat -gc 5811  2000 10000
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
34944.0 34944.0  0.0    0.0   279616.0 56627.5   699072.0   13979.2   21248.0 20630.5 2560.0 2386.8      0    0.000   1      0.338    0.338
34944.0 34944.0  0.0    0.0   279616.0 56627.5   699072.0   13979.2   21248.0 20630.5 2560.0 2386.8      0    0.000   1      0.338    0.338

根据压测,结合这个GC各个分代的情况,加之对业务的理解,推断是否存在不合理的地方。


-gcutil 输出主要关注已使用空间占总空间的百分比

监视内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比

[root@artisan ~]# jstat -gcutil 5811
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
  0.00   0.00  24.75   2.00  97.09  93.23      0    0.000     1    0.338    0.338
[root@artisan ~]# jstat -gcutil 5811 2000 10000


参数解读

  • S0:幸存1区当前使用比例
  • S1:幸存2区当前使用比例
  • E:伊甸园区使用比例
  • O:老年代使用比例
  • M:元数据区使用比例
  • CCS:压缩使用比例
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间


-gccause 额外输出导致上一次GC产生的原因

与-gcutil功能一样,但是会额外输出导致上一次GC产生的原因

[root@artisan ~]# jstat -gccause 5811
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC                 
  0.00   0.00  25.75   2.00  97.09  93.23      0    0.000     1    0.338    0.338 Metadata GC Threshold No GC               
[root@artisan ~]# jstat -gccause 5811 2000 10000
  • LGCC : 上一次GC的原因

堆内存统计

[root@artisan ~]# jstat -gccapacity 5811
 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC 
349504.0 349504.0 349504.0 34944.0 34944.0 279616.0   699072.0   699072.0   699072.0   699072.0      0.0 1069056.0  21248.0      0.0 1048576.0   2560.0      0     1
[root@artisan ~]# jstat -gccapacity 5811 2000 10000  --> 2秒输出一次 输出1万次


参数解读


NGCMN:新生代最小容量

NGCMX:新生代最大容量

NGC:当前新生代容量

S0C:第一个幸存区大小

S1C:第二个幸存区的大小

EC:伊甸园区的大小

OGCMN:老年代最小容量

OGCMX:老年代最大容量

OGC:当前老年代大小

OC:当前老年代大小

MCMN:最小元数据容量

MCMX:最大元数据容量

MC:当前元数据空间大小

CCSMN:最小压缩类空间大小

CCSMX:最大压缩类空间大小

CCSC:当前压缩类空间大小

YGC:年轻代gc次数

FGC:老年代GC次数


新生代垃圾回收统计


[root@artisan ~]# jstat -gcnew 5811
 S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT  
34944.0 34944.0    0.0    0.0 15  15    0.0 279616.0  56627.5      0    0.000
[root@artisan ~]# jstat -gcnew 5811  2000 10000 --> 2秒输出一次 输出1万次

参数解读


S0C:第一个幸存区的大小

S1C:第二个幸存区的大小

S0U:第一个幸存区的使用大小

S1U:第二个幸存区的使用大小

TT:对象在新生代存活的次数

MTT:对象在新生代存活的最大次数

DSS:期望的幸存区大小

EC:伊甸园区的大小

EU:伊甸园区的使用大小

YGC:年轻代垃圾回收次数

YGCT:年轻代垃圾回收消耗时间


新生代内存统计

[root@artisan ~]# jstat -gcnewcapacity 5811 
  NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC      YGC   FGC 
  349504.0   349504.0   349504.0  34944.0  34944.0  34944.0  34944.0   279616.0   279616.0     0     1
[root@artisan ~]# jstat -gcnewcapacity 5811 2000 10000 --> 2秒输出一次 输出1万次


参数解读


NGCMN:新生代最小容量

NGCMX:新生代最大容量

NGC:当前新生代容量

S0CMX:最大幸存1区大小

S0C:当前幸存1区大小

S1CMX:最大幸存2区大小

S1C:当前幸存2区大小

ECMX:最大伊甸园区大小

EC:当前伊甸园区大小

YGC:年轻代垃圾回收次数

FGC:老年代回收次数


老年代垃圾回收统计


[root@artisan ~]# jstat -gcold 5811 
   MC       MU      CCSC     CCSU       OC          OU       YGC    FGC    FGCT     GCT   
 21248.0  20630.5   2560.0   2386.8    699072.0     13979.2      0     1    0.338    0.338
[root@artisan ~]# jstat -gcold 5811  2000 10000  --> 2秒输出一次 输出1万次



参数解读

  • MC:方法区大小
  • MU:方法区使用大小
  • CCSC:压缩类空间大小
  • CCSU:压缩类空间使用大小
  • OC:老年代大小
  • OU:老年代使用大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间


老年代内存统计

[root@artisan ~]# jstat -gcoldcapacity 5811 
   OGCMN       OGCMX        OGC         OC       YGC   FGC    FGCT     GCT   
   699072.0    699072.0    699072.0    699072.0     0     1    0.338    0.338
[root@artisan ~]# jstat -gcoldcapacity 5811 2000 10000


参数解读

  • OGCMN:老年代最小容量
  • OGCMX:老年代最大容量
  • OGC:当前老年代大小
  • OC:老年代大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间


元数据空间统计

[root@artisan ~]# jstat -gcmetacapacity 5811 
   MCMN       MCMX        MC       CCSMN      CCSMX       CCSC     YGC   FGC    FGCT     GCT   
       0.0  1069056.0    21248.0        0.0  1048576.0     2560.0     0     1    0.338    0.338
[root@artisan ~]# jstat -gcmetacapacity 5811  2000 10000


参数解读


MCMN:最小元数据容量

MCMX:最大元数据容量

MC:当前元数据空间大小

CCSMN:最小压缩类空间大小

CCSMX:最大压缩类空间大小

CCSC:当前压缩类空间大小

YGC:年轻代垃圾回收次数

FGC:老年代垃圾回收次数

FGCT:老年代垃圾回收消耗时间

GCT:垃圾回收消耗总时间


运行情况预估


jstat 会用了哈

主要是利用jstat -gc pid 算出系统的关键参数 ,结合我们之前梳理的理论知识(这个没有,那基本上是不太可行了) ,先设置一些初始值,然后根据压测情况合理调整。

主要观察一下几点


【年轻代对象增长的速率】


可以执行命令 jstat -gc pid 2000 100(每隔2秒执行1次命令,共执行100次),通过观察EU(eden区的使用)来估算每秒eden大概新增多少对象.

如果系统负载不高,可以把频率2秒调大一些观察整体情况。


要考虑: 系统高峰期和低谷期间的压力,肯定是不一样的,总和考虑。


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


知道年轻代对象增长速率我们就能推根据eden区的大小推算出Young GC大概多久触发一次,Young GC的平均耗时可以通过 YGCT/YGC 公式算出,根据结果我们大概就能知道系统大概多久会因为Young GC的执行而卡顿多久。


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


这个因为之前已经大概知道Young GC的频率,假设是每5分钟一次,那么可以执行命令 jstat -gc pid 300000 10 ,观察每次结果eden,survivor和老年代使用的变化情况,在每次gc后eden区使用一般会大幅减少,survivor和老年代都有可能增长,这些增长的对象就是每次Young GC后存活的对象,同时还可以看出每次Young GC后进去老年代大概多少对象,从而可以推算出老年代对象增长速率。


【Full GC的触发频率和每次耗时】


知道了老年代对象的增长速率就可以推算出Full GC的触发频率了,Full GC的每次耗时可以用公式 FGCT/FGC 计算得出。


优化思路其实简单来说就是尽量让每次Young GC后的存活对象小于Survivor区域的50%,都留存在年轻代里。尽量别让对象进入老年代。尽量减少Full GC的频率,避免频繁Full GC对JVM性能的影响。

相关文章
|
2月前
|
DataWorks Java 关系型数据库
DataWorks常见问题之将预警信息发送至邮箱
DataWorks是阿里云提供的一站式大数据开发与管理平台,支持数据集成、数据开发、数据治理等功能;在本汇总中,我们梳理了DataWorks产品在使用过程中经常遇到的问题及解答,以助用户在数据处理和分析工作中提高效率,降低难度。
41 1
|
4月前
|
监控 架构师 Java
JVM 11 调优指南:如何进行JVM调优,JVM调优参数
JVM 11的优化指南:如何进行JVM调优,以及JVM调优参数有哪些”这篇文章将包含JVM 11调优的核心概念、重要性、调优参数,并提供12个实用的代码示例,每个示例都会结合JVM调优参数和Java代码
118 2
|
4月前
|
存储 缓存 监控
JVM 21 的调优指南:如何进行JVM调优,JVM调优参数
聊聊关于JVM 21的优化指南。这篇文章将会深入探讨如何进行JVM调优,介绍一些关键的JVM调优参数,并提供12个实用的代码示例。由于篇幅较长,我会分几个部分来详细讲解,之前写的也有33篇系列教程JVM调优实战打击也可以去围观。
115 0
|
4月前
|
监控 架构师 Java
JVM 8 调优指南:如何进行JVM调优,JVM调优参数
这篇文章将详细介绍如何进行JVM 8调优,包括JVM 8调优参数及其应用。此外,我将提供12个实用的代码示例,每个示例都会结合JVM启动参数和Java代码。JVM调优是指通过调整Java虚拟机的配置来提升Java应用程序的性能。这包括优化堆内存设置、选择合适的垃圾收集器以及调整其他性能相关的参数。
215 0
|
2月前
|
缓存 算法 安全
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(二)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
18 0
|
2月前
|
缓存 Java C#
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(一)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
84 0
|
4月前
|
监控 安全 架构师
JVM 17 调优指南:如何进行JVM调优,JVM调优参数
在这篇文章中,我会详细介绍JVM调优的概念、重要性和具体的JVM调优参数。此外,我将提供12个实用的代码示例,每个示例都会包含JVM调优参数和相应的Java代码。JVM调优是调整和配置Java虚拟机(JVM)的过程,以便最大限度地提高应用程序的性能和效率。这涉及到调整内存设置、选择合适的垃圾收集器,以及配置各种性能参数。
268 0
|
2天前
|
Java
jvm配置参数,查看大对象直接分配到老年代
jvm配置参数,查看大对象直接分配到老年代
|
4天前
|
人工智能 运维 Java
Serverless 应用引擎产品使用之在阿里云函数计算中设置JVM参数如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
11 0
|
5月前
|
Java 应用服务中间件 Linux
JVM调优总结(一)之参数配置说明与实例
JVM调优总结(一)之参数配置说明与实例
167 0