虚拟机回收算法怎么选?,JVM垃圾回收器对比指南

虚拟机回收算法没有银弹,核心是在吞吐量、停顿时间和内存占用之间做权衡;选型时先看应用场景是延迟敏感型还是吞吐优先型,再决定用分代、G1还是ZGC。

虚拟机回收算法有哪些:从分代到低延迟

基础回收算法:标记-清除、复制与标记-整理

JVM的垃圾回收算法演进,本质上是在解决三个问题:哪些内存可回收、怎么高效回收、怎么减少回收时的停顿,早期基础算法奠定了整个体系的基础。

JVM垃圾回收机制
加载中
JVM垃圾回收机制
  • 标记-清除(Mark-Sweep):先遍历对象图标记存活对象,再统一清除未标记对象,该算法实现简单,但会产生大量内存碎片,后续分配大对象时容易触发频繁的Full GC。
  • 复制(Copying):把堆内存分成两块,只使用一块,GC时把存活对象复制到另一块,然后整块清空,内存分配效率高,不发生碎片,但可用内存空间被压缩一半,HotSpot虚拟机的新生代就采用这个思路,把Eden区与两个Survivor区按8:1:1比例划分。
  • 标记-整理(Mark-Compact):标记阶段与标记-清除一致,但后续将所有存活对象向内存一端移动,然后清理掉边界以外的内存,避免碎片,但移动对象会更新引用,增加停顿时间,老年代常用该算法或其变体。

现代垃圾回收器:CMS、G1、ZGC和Shenandoah

算法是理论,垃圾回收器是工程实现,各大JDK版本演变,催生了针对不同场景的回收器。

  • CMS(Concurrent Mark Sweep):主打低停顿,并发标记和并发清除,问题是并发模式失败时退化为Serial Old,且存在浮动垃圾和内存碎片,JDK 9开始被废弃,JDK 14正式移除。
  • G1(Garbage First):把堆划分为多个Region区域,维护优先列表,优先回收价值最大的Region,在可控停顿时间内尽可能提高吞吐量,兼顾延迟和吞吐,成为JDK 11之后服务端默认垃圾回收器。
  • ZGC(Z Garbage Collector):基于Region内存布局,染色指针和读屏障实现几乎全部的并发,停顿时间不随堆大小增长而增长,JDK 15进入正式版本。
  • Shenandoah:与ZGC目标类似,JDK 12引入,采用转发指针和碰撞指针,后续版本不断优化,适配需要低延迟的应用。

g1和zgc怎么选:延迟与吞吐的权衡

这是现阶段最常被问到的对比,毕竟从JDK 17到JDK 21,G1和ZGC是最主流的两个选择。

从延迟上看,ZGC的设计目标是尽量把停顿压制在10毫秒以内,甚至更短,G1的停顿预测模型依赖历史数据,默认目标为200毫秒,实际调优后可降到50毫秒左右,但堆越大、对象分配越快,越难保证稳定低延迟。

虚拟机回收算法怎么选?,JVM垃圾回收器对比指南

从吞吐量上看,G1在多数业务场景下更占优势,ZGC引入了染色指针等额外开销,读屏障和并发处理会占用一定CPU资源,如果应用对停顿不敏感,且追求更高CPU利用率,G1往往比ZGC表现更好。

从堆大小与JDK版本看,堆小于4GB时可以优先考虑G1,堆大于16GB且对停顿敏感时,ZGC是更合适的选择,JDK 21中ZGC还支持了分代模式,进一步缩小了与G1在吞吐量上的差距。

选择建议如下

  • 交易系统、实时推荐、游戏服务端等要求毫秒级响应的场景,选ZGC或Shenandoah。
  • 数据处理、离线任务、Web应用等追求高吞吐且能容忍秒级停顿的场景,G1仍是稳妥之选。
  • 小堆内存且无需复杂调优的场景,可以用JDK默认的G1加上-Xmx-Xms启动参数,先跑起来再观察日志。

如何选择适合场景的回收策略:三步定位法

面对五花八门的算法和回收器,直接背参数没有意义,建议用下面的思路落地。

第一步:明确业务容忍的停顿标准

跟业务方确认两个问题:单次GC最长能接受多久?一分钟内能接受几次Full GC?如果答案是不能超过50毫秒且不允许Full GC,那么CMS就已经出局,G1需要精细调优,ZGC几乎不需要干预,如果业务是跑批任务,凌晨执行,一次Full GC停顿十几秒也无所谓,那G1甚至Parallel GC都完全够用。

第二步:观察当前GC日志与内存变化

在测试环境或灰度环境,用以下参数打印GC日志:

-Xlog:gc:file=gc.log:time,uptime,level,tags

多跑一段时间,观察Young GC的频率、平均停顿和Full GC的次数,如果新生代每次GC后存活对象比例波动大,说明对象生命周期不稳定;如果老年代持续增长且Full GC频繁,说明堆配置或回收器选择不合理。

进一步配合jstat -gcutiljmap -histo查看各代占用和对象分布,这些是JDK自带的工具,不需要额外安装,操作路径为:启动应用后,在命令行直接执行jstat -gcutil <pid> 1000 10,每1秒采样一次,共采样10次。

第三步:根据场景特征确定回收策略

行业共识认为,没有最好只有最合适的回收器,判断依据可从以下维度展开。

  • 对象存活率:新生代存活率低(小于10%)时,复制算法的效率极高,存活率超过50%时,复制算法会频繁把对象拷来拷去,不如标记-整理实在。
  • CPU核心数:ZGC和Shenandoah需要较多CPU线程做并发标记和并发清理,如果服务器只有2核4线程,G1更省心,ZGC的CPU消耗可能挤占业务线程资源。
  • 虚拟机回收算法怎么选?,JVM垃圾回收器对比指南

  • 堆内存大小:大堆(几十GB甚至上百GB)遇到G1容易因并发标记周期长带来较长的停顿,ZGC在超大堆上的优势更明显。
  • JDK版本与生态:老项目还在JDK 8上,只能选G1或CMS,ZGC根本没法用,新项目直接奔JDK 17,老老实实用G1起步,等真的遇到长停顿再切ZGC也不迟。

分代回收机制:新生代、老年代与元空间

不管选哪种回收器,理解分代模型能让调优更有章法。

新生代与老年代的回收路径

对象优先在Eden区分配,Eden区填满触发Minor GC,存活对象进入Survivor区,经历一定次数的Minor GC后,年龄达到阈值(默认15)的对象晋升到老年代,大对象直接进入老年代,避免在Eden和Survivor之间反复复制。

老年代空间不足时触发Major GC/Full GC,此时回收的代价远高于Minor GC,G1和ZGC都试图减少Full GC的发生,特别是ZGC,几乎不触发Full GC。

元空间与内存泄漏排查

JDK 8之后永久代被移除,改为元空间,元空间使用本地内存,触发回收的条件是类加载器及其加载的类无引用,频繁动态生成类的框架(如Spring、CGLIB)若使用不当,容易导致元空间溢出,排查时用jcmd <pid> GC.class_stats查看类统计信息。

以下表格对比主流回收器的核心维度,方便快速筛选:

回收器 适用的JDK版本 暂停目标 吞吐量 典型场景
Parallel GC JDK 8及以后 很高 批量计算、后台任务
G1 JDK 8u40+ 可控 较高 通用服务端应用
ZGC JDK 15+ 极低 中等 大堆、低延迟场景
Shenandoah JDK 12+ 极低 中等 与ZGC类似,但实现不同

低延迟场景的回收策略实践

延迟敏感型应用怎么调

如果应用是K线行情推送或在线支付,核心诉求就是平均GC停顿在10毫秒以下,先把堆内存固定起来,-Xms-Xmx设成相同值,避免扩容时触发Full GC,然后使用ZGC,加参数-XX:+UseZGC,再配套-XX:ConcGCThreads控制并发GC线程数,通常设置为CPU核数的四分之一到三分之一。

调完后,用线上流量压测观察P99延迟,如果延迟曲线在GC周期后出现尖刺,说明ZGC的并发周期与业务高峰重叠,可以错开GC时间或调大预留内存。

虚拟机回收算法怎么选?,JVM垃圾回收器对比指南

吞吐优先型应用怎么调

类似离线报表、数据清洗程序,跑得越快越好,直接使用Parallel GC,参数为-XX:+UseParallelGC,再设置-XX:ParallelGCThreads为CPU物理核数,同时适当增大新生代比例,比如-XX:NewRatio=1,让更多对象在新生代就消亡,减少晋升。

如果遇到老年代经常满了但堆内存还有不少空闲的情况,检查是否有大数组或缓存长期持有对象引用,这时候调GC参数不如修代码。

常见调优误区

  • 盲目追求低延迟,给4G堆的应用强行上ZGC,可能比G1更慢。
  • 堆内存设得越大越好,实际上超过物理内存会导致频繁的swap,反而拖垮性能。
  • 忽略GC日志的保留时间,日志量很大但没留足够天数的历史,排障时无从下手。

聊聊R语言环境下的回收机制 (相关衍生话题)

不少统计建模或数据分析的朋友会问,R语言的GC是不是和Java一样,R语言采用一种简单的分代GC,主要使用标记-清除策略,并引入写屏障管理写入屏障,R中的gc()函数能强制触发GC,但多数情况下不需要手动干预,如果做大内存的向量计算,R的GC效率不如JVM的并发收集器,这也是R生态处理超大数据集不如Java高效的原因之一,至于R和Java的回收算法对比,可以简单理解为R重视简单可靠,Java重视可调优和低延迟。

Q&A:虚拟机回收算法常见疑问

为什么Full GC之后老年代内存还是缓慢增长?

可能是某个缓存对象始终被强引用,GC无法回收,用jmap -dump:format=b,file=heap.hprof <pid>导出堆快照,再用MAT或VisualVM分析,重点关注大对象和线程栈中的局部变量引用。

用了G1之后,还需要手动设置SurvivorRatio吗?

G1的Survivor区大小是动态调整的,手动设置-XX:SurvivorRatio效果不稳定,建议直接依赖G1的自适应逻辑,只关注-XX:G1NewSizePercent-XX:G1MaxNewSizePercent这两个参数来控制新生代占比。

生产环境从CMS切换到G1或ZGC,需要改动代码吗?

不需要改业务代码,但需重新验证GC参数和监控指标,CMS的一些参数在G1或ZGC下不生效,比如-XX:CMSInitiatingOccupancyFraction,切换前把旧参数清理干净,重新参考新回收器的推荐配置,并在压测环境跑一轮完整的排查。

垃圾回收没有万能答案,理解每种算法的取舍,再结合业务停顿标准和硬件资源做出选择,就能让JVM在绝大多数场景下安静工作,先跑起来采集日志,用数据驱动选型,比上来就堆参数更可靠。

首发原创文章,作者:王坚‌,如若转载,请注明出处:https://idctop.com/article/614355.html

(0)
白云一键重装系统好用吗,小白操作会不会出问题?
上一篇 2026年9月1日 10:55
怎样把图片制作成视频?新手能快速学会吗,图片转视频用什么软件
下一篇 2026年9月1日 10:57

相关推荐

  • html5video网站怎么用?html5video网站源码哪里下载

    HTML5视频网站的核心优势在于无需插件即可跨设备流畅播放,支持自适应码率与字幕集成,是2026年构建现代化多媒体内容平台的首选技术架构,在移动互联网深度渗透的今天,用户对于视频内容的消费习惯已经发生了根本性的转变,过去那种依赖Flash插件、需要特定浏览器才能观看的时代早已终结,无论是手机端还是桌面端,用户都……

    服务器宽带 2026年6月12日
    2800
  • 上行带宽和下行带宽区别?上行带宽和下行带宽哪个重要?

    上行带宽和下行带宽区别?最核心的结论在于数据传输的方向不同:下行带宽决定了你从互联网获取信息的速度,直接影响观影、下载体验;上行带宽决定了你向互联网发送信息的速度,直接影响直播、视频会议及云存储备份的效率,对于企业用户而言,忽视上行带宽的配置往往会导致业务卡顿,选择简米科技等专业服务商提供的对称带宽解决方案,能……

    2026年3月7日
    12400
  • 广州600g高防ddos服务器怎么防,高防服务器能防御哪些攻击

    广州600G高防DDoS服务器的防御核心在于“超大带宽清洗能力+智能流量调度+硬件防火墙联动”,构建从网络层到应用层的立体防护体系,针对华南地区高发的流量攻击,单纯依赖基础防御无法抵御 SYN Flood、UDP Flood 及 CC 攻击的混合打击,必须采用集群式清洗中心配合精准的流量牵引技术,才能确保业务在……

    2026年3月31日
    9200
  • 西安服务器租用合同带宽条款有哪些陷阱?,怎么避免陷阱?

    西安服务器租用合同里带宽条款是整个合同的核心,带宽类型、计费方式和超标处理规则直接决定你的实际使用成本和网站稳定性,签约前必须逐字确认,带宽条款里最容易踩的坑:独享和共享的猫腻很多第一次在西安租服务器的朋友,看到“独享10M”“共享100M”就以为捡到了便宜,这两个词在合同里的含义差距巨大,独享带宽指你单独使用……

    服务器宽带 2026年8月9日
    600
  • 武汉互联网公司业务扩张期整机租用如何平滑升级,怎么选?

    避开迁移陷阱的三大要点业务扩张期整机租用平滑升级的核心在于前期架构预留弹性,过程中采用热迁移技术,并选择支持按需升级的武汉本地服务商,业务扩张期服务器租用怎么选?先看这五个维度整机租用不是一次性采购,而是伴随业务增长持续调整的过程,武汉互联网公司常见扩张场景包括:用户量激增、新业务上线、数据存储扩容,在这些阶段……

    服务器宽带 2026年8月9日
    400
  • 买SSL证书怎么选?SSL证书购买攻略

    挑选SSL证书的核心在于平衡安全性、兼容性、预算与品牌信任度,建议优先选择支持多域名且具备自动续期功能的DV或OV证书,避免盲目追求高价EV证书,在数字化时代,网站的安全标识已不再是单纯的装饰,而是用户建立信任的第一道门槛,面对市场上琳琅满目的证书类型,许多站长和运维人员往往陷入选择困难,挑选过程并不复杂,只要……

    2026年6月18日
    2610
  • WooCommerce如何更改产品分类顺序?WooCommerce产品分类排序方法

    在WooCommerce中更改产品分类顺序,最直接且推荐的方法是通过后台“产品”>“分类”菜单拖拽排序,或修改分类的“排序”字段数值,无需安装额外插件即可实现精准控制,很多电商运营者刚接触WooCommerce时,都会遇到产品分类显示混乱的问题,默认情况下,系统往往按照分类ID或创建时间排序,这显然不符合……

    2026年6月19日
    2200
  • http接口服务器是什么?http接口服务器租用费用是多少

    http接口服务器本质是充当客户端与后端业务逻辑之间的“翻译官”和“调度员”,通过标准化协议实现跨系统数据交互,选择时需重点考量并发处理能力、安全性配置及运维成本,http接口服务器核心架构与工作原理理解http接口服务器,首先要打破它只是“传话筒”的刻板印象,在现代微服务架构中,它更像是一个繁忙的物流分拣中心……

    2026年6月4日
    3900
  • access数据库怎么关联?access数据库多表关联查询

    Access数据库关联的核心在于通过“关系型视图”建立表间连接,利用主键与外键实现数据的自动同步与查询,这是构建高效、无冗余数据系统的关键步骤,在2026年的数据管理环境中,许多中小企业依然依赖Access作为轻量级业务系统的后端,很多用户在面对多表数据时,往往陷入重复录入的泥潭,或者在查询时遇到数据对不上的困……

    2026年7月3日
    1310
  • Access数据库求和函数怎么用?Access数据库常用函数有哪些

    在Access数据库中,求和的核心函数是Sum(),它专门用于对数值型字段进行聚合计算,若需按组统计则必须配合GROUP BY子句使用,很多刚接触Access的用户都会遇到一个痛点:明明数据都在表里,为什么直接拉个报表或者写个查询,结果总是对不上?或者更糟糕的是,想算一下某个部门的总销售额,结果算出来全是零或者……

    2026年7月3日
    3500

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注