谈谈jvm的调优思路

发布于:2025-05-21 ⋅ 阅读:(19) ⋅ 点赞:(0)

目录

1、G1回收器

2、常用的回收器分类

1、cms

2、G1、Hotspot

3、ZGC

4、设置

3、常见的调优策略

3.1、设定大小

1、堆的大小

2、Region的大小

3、年轻代大小调整

3.2、设置最大停顿时间

3.3、设置标记和回收线程

3.4、并发周期触发阈值


背景

        正常情况下,都轮不到我们去调优,当jvm出现GC问题的时候,光通过修改参数,很难从根本上解决程序的问题。

        由于后续他人不好维护,且当前调整的jvm参数只适用于某段时刻程序的流量性能,因此不可扩展。

        因此,实际开发过程中,项目启动的时候,可以通过GC的回收机制、回收器的参数来进行规避。

更多GC回收,可参考:Java对象的内存布局及GC回收年龄的研究-CSDN博客


1、G1回收器

        最早出现在jdk7,在java17中默认,G1回收器,堆内存会被划分为Eden、suvivor、old区、Humongous区(存放大对象)。

如下图所示:

在每个region区可分为内存为2的幂等。

        堆内存被划分为不同的region区,每个region区大小是相等的。如果一个对象的大小占比超过region区的50%,则会被默认放到H区,后续也可以在H区方便回收对象。


2、常用的回收器分类

关于更多回收器的介绍,可参考:关于对JVM的知识整理_谈谈你对jvm的理解-CSDN博客

1、cms

jdk7,jdk8默认的,jdk14已经不支持。

2、G1、Hotspot

jdk8-17默认的回收器。

3、ZGC

jdk17出来,jdk21成为默认的回收器。

4、设置

启动jvm的时候,可以通过以下参数,指定jvm。

-XX:+UseCMSGC
-XX:+UseG1GC

3、常见的调优策略

3.1、设定大小

1、堆的大小

        一般将堆的大小固定,通过参数:        

-Xms -2048M -XMx  -2048M 固定为大小2G

2、Region的大小

        region的大小都是2的幂次,从1M->32M。

        在heap比较小的时候,可以将region设定1m,2m,反之设置较大。

-XX:G1heapRegionSize=4M

选择依据:

  • 默认值:堆大小/2048(最小1MB)

  • 大对象(>50%Region大小)会直接进入老年代

  • 超大对象(>整个Region)会分配在Humongous区域

3、年轻代大小调整

-XX:G1NewSizePercent=10  //年轻代最小占比
-XX:G1MaxNewSizePercent=30  //年轻代最大占比
  • 增大年轻代可减少GC频率但增加单次停顿时间

  • 观察Young GC时间调整至占整体停顿目标的1/3左右

3.2、设置最大停顿时间

        G1的停顿预测模型,默认停顿时间为200ms,如果对于延迟较低的场景,可以通过设置MaxGCpauseMills来进行设置停顿时间。

-XX:MaxGCPauseMills=100
  • 设置过低会导致GC更频繁

  • 设置过高可能导致单次GC停顿时间过长

3.3、设置标记和回收线程

G1在标记和回收阶段,都属于多线程的操作。

-XX:ParalleGCThreads=8 //并行回收线程数为8(默认cpu核心数)
-XX: ConGCThreads = 8/4 //并行标记线程数为2

3.4、并发周期触发阈值

-XX:InitiatingHeapOccupancyPercent=45  # 默认45%
  • 老年代占用达到该比例时启动并发标记周期

  • 过早触发(值设高)会导致Full GC风险

  • 过晚触发(值设低)会增加并发标记负担

完整的命令如下

java -Xms4G -Xmx4G \
     -XX:+UseG1GC \
     -XX:MaxGCPauseMillis=200 \
     -XX:G1HeapRegionSize=4M \
     -jar  app.jar

总结

        调整JVM的堆内存可以帮助避免内存溢出,提高垃圾回收的效率。合适的垃圾回收器能够提高应用的响应速度和吞吐量。

        在实际操作中,建议逐步调整参数,并结合性能监控工具来评估调优效果。


网站公告

今日签到

点亮在社区的每一天
去签到