程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

【对线面试官】聊聊JVM调优经验?(如何进行jvm调优步骤详解面试题)

balukai 2025-07-23 13:04:18 文章精选 3 ℃

一、99.9%的人没有JVM调优经验

其实,JVM调优并不是每个开发者都会接触到的技能,原因很简单:JVM通常不需要调优

如果你的 JVM 真的出现了严重的 GC 压力,第一步想到的应该是优化代码,而不是直接上手去调整 JVM 参数。因为调整 JVM 可能带来以下问题:

  1. 不可维护:调优后,可能下一个维护者难以理解这些修改。
  2. 不可拓展:假设当前流量已经优化好了,但未来流量大幅变化时,这些参数可能失效。

尽管如此,面试时常常会有面试官问起 JVM 调优。那么,他们真的在问 JVM 调优的经验吗?

二、面试官实际上想问什么?

他们更多的是在考察以下方面:

  • 你对 JVM GC 的理解
  • 你对不同 GC 回收器的熟悉度
  • 你是否了解常见的 JVM GC 参数配置

接下来我们以 Java 17 中的G1垃圾回收器为例,来看一些常见的 GC 相关参数。

在 G1 垃圾回收器中,堆内存被划分为多个Region,虽然这些 Region 的大小是相同的,但是它们属于不同的代。了解这些原理有助于我们更好地优化 JVM 的 GC 性能。

内存区域划分:

  • E(Eden)区:存放新创建的对象
  • S(Survivor)区:存放从Eden区存活下来的对象
  • O(Old)区:存放长期存活的对象
  • H(Humongous)区:专门存放超大对象

大对象的判定标准: 当一个对象的大小超过单个 Region(内存区域) 大小的 50%(0.5个Region)时,它就被视为大对象(Humongous对象)

三、常见的垃圾回收器

目前常见的垃圾回收器包括下面 3 种:

  • CMS (Concurrent Mark-Sweep): JDK 14之后不再支持
  • G1 (Garbage First): JDK 8-17版本的默认垃圾回收器
  • ZGC (Z Garbage Collector): 从JDK 21开始,成为默认的垃圾回收器。

在启动 JVM 时,可以通过指定参数来使用不同的垃圾回收器。

-XX:+UseZGC
-XX:+UseG1GC
-XX:+UseConcMarkSweepGC

四、常见的调优策略

1. 设置堆大小

一般来说,我们建议将 JVM 的堆内存大小进行固定,避免堆内存发生动态扩缩容。

# 例如固定为2GB
-Xms 2048M -XMx 2048M

固定堆内存的好处:

  • 避免堆的扩缩容:堆内存的扩缩容会影响 GC 的时间,带来更多的停顿时间,尤其是 G1这 种需要预测停顿时间的垃圾回收器,会导致预测变得不准确。
  • 减少内存碎片:在 G1 中,堆内存被划分为多个 Region,如果堆大小不固定,Region 的大小也会不固定,可能导致内存浪费。

2. 设置Region大小

G1 将堆内存划分为多个大小相等的 Region,Region 的大小一般是 2 的幂,从 1MB 到 32MB 不等。

合理调整Region大小能更好地配合应用的实际需求,提升性能表现,减少停顿时间,并且优化堆内存管理。

对于较小的堆内存,建议设置较小的 Region 大小,例如2MB或4MB。 对于较大的堆内存,建议设置较大的Region大小。

# 例如设置Region 为4M
-XX:G1HeapRegionSize=4M

3. 设置最大目标停顿时间

上面说过 G1 垃圾回收器的最大特点是停顿预测模型。默认的停顿时间为 200ms。

因此我们可以设置一个目标停顿时间:

# 设置目标停顿时间为 100 ms
-XX:MaxGCPauseMillis=100

注意: JVM 会尽量保证垃圾回收停顿时间不超过这个值,但不能完全保证。所以针对一些延迟敏感的场景,可以适当调小停顿时间。

4. 设置标记线程数和回收线程数

G1 在进行标记对象为垃圾和回收垃圾时,都是多线程操作的。 因此我们可以根据需要去调整线程数。

# 并行回收线程数(默认值是 CPU 核心数)
-XX:ParallelGCThreads=8
# 并发标记线程数
-XX:ConcGCThreads=4

说到最后,这些调优参数在哪使用呢? 其实是在我们运行服务时设置的,例如:

# -Xms4G:设置JVM堆内存的初始大小为4GB。这意味着JVM启动时会分配4GB的堆内存
# -Xmx4G:设置JVM堆内存的最大大小为4GB。JVM堆的大小不会超过4GB
# -XX:+UseG1GC:启用G1垃圾回收器
# -XX:MaxGCPauseMillis=200:设置G1垃圾回收器的最大目标停顿时间为200 毫秒
# -XX:G1HeapRegionSize=4M:设置G1垃圾回收器的Region大小为4MB
# -XX:InitiatingHeapOccupancyPercent=45:设置堆的占用比例为45%。当堆内存的占用达到该比例时,G1垃圾回收器会开始触发并发标记过程,准备进行垃圾回收
# -Xlog:gc*,gc+heap=debug:file=gc.log:启用GC日志记录,gc*表示记录所有GC日志,gc+heap=debug表示记录GC过程中堆内存的详细调试信息,并将日志输出到gc.log文件中。
java -Xms4G -Xmx4G \
     -XX:+UseG1GC \
     -XX:MaxGCPauseMillis=200 \
     -XX:G1HeapRegionSize=4M \
     -XX:InitiatingHeapOccupancyPercent=45 \
     -Xlog:gc*,gc+heap=debug:file=gc.log \
     -jar my-app.jar

Tags:

最近发表
标签列表