掘金 后端 ( ) • 2024-05-21 14:27

公众号首图__2024-05-20+22_33_14.jpg

JVM 调优是一个很大的话题,在回答“如何进行 JVM 调优?”之前,首先我们要回答一个更为关键的问题,那就是,我们为什么要进行 JVM 调优?

只有知道了为什么要进行 JVM 调优之后,你才能准确的回答出来如何进行 JVM 调优?

要进行 JVM 调优无非就是以下两种情况:

  1. 目标驱动型的 JVM 调优,如,我们是为了最短的停顿时间所以要进行 JVM 调优,或者是我们为了最大吞吐量所以要进行 JVM 调优等。
  2. 问题驱动型的 JVM 调优,因为生产环境出现了频繁的 FullGC 了,导致程序执行变慢,所以我们要进行 JVM 调优。

所以,针对不同的 JVM 调优的手段和侧重点也是不同的。

总的来说,JVM 进行调优的流程如下:

  1. 确定 JVM 调优原因
  2. 分析 JVM(目前)运行情况
  3. 设置 JVM 调优参数
  4. 压测观测调优后的效果
  5. 应用调优后的配置

具体来说它们的执行如下。

1.确定JVM调优原因

先确定是目标驱动型的 JVM 调优,还是问题驱动型的 JVM 调优。

如果是目标性的 JVM 调优,那么 JVM 调优实现思路就比较简单了,如:

  1. 以最短停顿时间为目标的调优,只需要将垃圾收集器设置成以最短停顿时间的为目标的垃圾收集器即可,如 CMS 收集器或 G1 收集器。
  2. 以吞吐量为目标的调优,只需要将垃圾收集器设置为 Parallel Scavenge 和 Parallel Old 这种以吞吐量为主要目标的垃圾回收器即可。

如果是以问题驱动的 JVM 调优,那就要先分析问题是什么,然后再进行下一步的调优了。

2.分析JVM运行情况

我们可以借助于目前主流的监控工具 Prometheus + Grafana 和 JDK 自带的命令行工具,如 jps、jstat、jinfo、jstack 等进行 JVM 运行情况的分析。

主要分析的点是 Young GC 和 Full GC 的频率,以及垃圾回收的执行时间。

3.设置JVM调优参数

常见的 JVM 调优参数有以下几个:

  • 调整堆内存大小:通过设置 -Xms(初始堆大小)和 -Xmx(最大堆大小)参数来调整堆内存大小,避免频繁的垃圾回收。
  • 选择合适的垃圾回收器:根据应用程序的性能需求和特点,选择合适的垃圾回收器,如 Serial GC、Parallel GC、CMS GC、G1 GC 等。
  • 调整新生代和老年代比:通过设置 -XX:NewRatio 参数来调整新生代和老年代的比例,优化内存分配。
  • 设置合适的堆中的各个区域比例:通过设置 -XX:SurvivorRatio 参数和 -XX:MaxTenuringThreshold 参数来调整 Eden 区、Survivor 区和老年代的比例,避免过早晋升和过多频繁的垃圾回收。
  • 设置对象从年轻代进入老年代的年龄值:-XX:InitialTenuringThreshold=7 表示 7 次年轻代存活的对象就会进入老年代。
  • 设置元空间大小:在 JDK 1.8 版本中,元空间的默认大小会根据操作系统有所不同。具体来说,在 Windows 上,元空间的默认大小为 21MB;而在 Linux 上,其默认大小为 24MB。然而如果元空间不足也有可能触发 Full GC 从而导致程序执行变慢,因此我们可以通过 -XX:MaxMetaspaceSize= 设置元空间的最大容量。

4.压测观测调优后的效果

JVM 参数调整之后,我们要通过压力测试来观察 JVM 参数调整前和调整后的差别,以确认调整后的效果。

5.应用调优后的配置

在确认了 JVM 参数调整后的效果满足需求之后,就可以将 JVM 的参数配置应用与生产环境了。

课后思考

除了以上常见的 JVM 调优参数之外,还有没有其他重要的参数设置呢?

本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。