当前位置: 首页 > news >正文

Java垃圾回收机制理论算法及使用

我们来深入、系统地解析 Java 垃圾回收(Garbage Collection, GC)机制。这是 JVM 性能调优的核心,尤其对你提到的游戏等低延迟场景至关重要。


一、核心思想:分代收集理论 (Generational Collection)

这是当前大多数 JVM 垃圾收集器的设计基础。其核心假设是:

  1. 弱分代假说 (Weak Generational Hypothesis):绝大多数对象都是“朝生夕死”的,即很快变得不可达。

  2. 强分代假说 (Strong Generational Hypothesis):熬过越多次垃圾收集过程的对象,就越难以消亡。

基于这两个假说,Java 堆被划分为不同的区域(代),以便采用最合适的收集策略。

堆内存分代
区域描述特点适用算法
新生代 (Young Generation)新创建的对象首先在这里分配。- 区域小,但GC非常频繁。
- 98%的对象在这里被回收。
复制算法
老年代 (Old/Tenured Generation)在新生代中经历多次 GC 后仍然存活的对象会被晋升到这里。- 区域大,GC频率较低。
- 存放长期存活的大对象。
标记-清除标记-整理
元空间 (Metaspace) (方法区)存放类元信息、常量池等。- 在本地内存中,不连续。
- GC条件苛刻。
主要是标记-清除
GC 类型

基于分代的回收动作分为两种:

  1. Young GC / Minor GC

    • 触发条件:当新生代 Eden 区满时触发。

    • 过程:只收集新生代。存活的对象从 Eden 和 From Survivor 区被复制到 To Survivor 区,年龄+1。如果 To 区满或对象年龄超过阈值(默认15),则直接晋升到老年代。一次 Young GC 会引发 STW (Stop-The-World),即暂停所有应用线程。

  2. Full GC / Major GC

    • 触发条件:老年代空间不足、元空间不足、System.gc()调用、Heap Dump 等。

    • 过程:收集整个堆,包括新生代、老年代和元空间(通常)。STW 时间通常很长,对延迟敏感的应用(如游戏、交易系统)是灾难性的。优化目标就是尽量避免或减少 Full GC。


二、垃圾收集算法 (GC Algorithms)

这是收集器实现的理论基础。

  1. 标记-清除 (Mark-Sweep)

    • 过程:首先标记所有需要回收的对象,标记完成后统一回收。

    • 优点:简单。

    • 缺点效率不高;会产生大量内存碎片,导致后续无法分配大对象而触发 Full GC。

    • 代表:CMS 的老年代收集。

  2. 复制 (Copying)

    • 过程:将内存分为两块,每次只使用一块。当这一块用完了,就将还存活的对象复制到另一块上,然后把已使用的内存空间一次清理掉。

    • 优点高效(只需遍历存活对象),没有碎片

    • 缺点内存利用率低,只有一半。

    • 应用:完美契合新生代(Eden:Survivor = 8:1:1),因为98%的对象都可被回收,复制的成本极低。

  3. 标记-整理 (Mark-Compact)

    • 过程:先标记所有需要回收的对象,让所有存活的对象都向内存空间的一端移动,然后直接清理掉边界以外的内存。

    • 优点没有内存碎片,内存利用率高。

    • 缺点:移动对象成本高,需要更新引用地址,STW 时间更长

    • 代表:Serial Old, Parallel Old。


三、主流垃圾收集器 (Garbage Collectors)

收集器是算法的具体实现。JDK 不同版本默认收集器在演变,没有最好的,只有最适合场景的。

收集器区域算法特点适用场景
Serial新生代复制单线程,STW 时间长。客户端模式,资源受限的嵌入式系统。
Parallel Scavenge / Parallel Old新生代/老年代复制/标记-整理JDK8 默认多线程,追求高吞吐量(用户代码运行时间/(用户代码运行时间+GC时间))。后台运算、科学计算、批处理任务。
CMS (Concurrent Mark Sweep)老年代标记-清除并发收集低停顿。追求最短回收停顿时间。互联网、B/S 架构的服务端。已废弃
缺点:1. 内存碎片。2. 对 CPU 资源敏感。3. 无法处理“浮动垃圾”,可能触发 Concurrent Mode Failure 导致 Full GC。
G1 (Garbage-First)整个堆Region化,复制+标记-整理JDK9+ 默认。将堆划分为多个 Region,优先回收价值最大(垃圾最多)的 Region。可预测的停顿时间模型面向服务端,大内存、多核CPU。平衡吞吐量和低延迟。
优点:并行与并发,分Region管理,空间整合(整体看是标记-整理,Region间是复制),可预测的停顿。
ZGC整个堆Region化着色指针读屏障JDK15 正式推出超低延迟STW < 1ms),可处理 TB 级堆内存。极致低延迟场景:游戏、金融交易、大数据平台。
Shenandoah整个堆Region化Brooks指针读屏障由 Red Hat 开发,与 ZGC 目标类似,低延迟。与 ZGC 主要区别在于实现方式(如并发压缩算法)。同 ZGC,同样是低延迟的优秀选择。

四、低延迟 GC(如 ZGC)对游戏的重要性

对于游戏服务器和客户端来说,GC 停顿是性能和体验的杀手

  1. 避免卡顿,保证帧率稳定

    • 一次数百毫秒的 Full GC 会导致游戏画面严重卡顿、角色失控、技能延迟,这在竞技类游戏中是致命的。ZGC 和 Shenandoah 将 STW 时间控制在惊人的 1 毫秒以内,人类几乎无法感知,从而保证了极致的流畅体验。

  2. 提升响应速度,保证游戏公平性

    • 在多人在线游戏中,服务器的响应速度直接决定了游戏的公平性和玩家的体验。长时间的 GC 停顿会导致服务器无法及时处理玩家的输入(如射击、移动),造成“网络延迟”的假象。低延迟 GC 确保了游戏世界的实时性和响应性。

  3. 支持更复杂的游戏世界和更大的玩家规模

    • 现代游戏需要加载大量资源(纹理、模型、地图),这些都会占用大量堆内存(数GB到数十GB)。传统的 GC(如 CMS、G1)在大堆下,停顿时间会显著增加。而 ZGC 和 Shenandoah 的停顿时间与堆大小无关,使得游戏开发者可以放心地使用大内存来构建更复杂、更宏大的游戏世界,同时支持更多玩家同屏竞技。

  4. 简化开发,降低调优成本

    • 使用传统 GC 时,工程师需要花费大量精力进行复杂的 JVM 参数调优(如堆大小、新生代大小、晋升年龄等)来尽量避免 Full GC。而 ZGC 等新一代收集器的设计目标就是 “开箱即用”,其参数极少,大大降低了开发和运维的复杂度,让开发者能更专注于游戏逻辑本身。

总结与选择建议

场景推荐收集器理由
个人学习、小型应用Serial / Parallel简单高效,无需复杂配置。
后台服务、大数据处理Parallel / G1追求高吞吐量,允许一定的停顿。
Web 应用、微服务G1JDK9+ 默认,在吞吐和延迟间取得良好平衡。
游戏、金融交易、实时系统ZGC / Shenandoah极致低延迟是核心需求,必须避免长停顿。

最终建议:对于任何新建的、对延迟有要求的项目(尤其是游戏服务器),如果使用 JDK 17 LTS 或更高版本,应优先考虑启用 ZGC-XX:+UseZGC),这是目前 Java 领域在低延迟方面最先进和成熟的选择之一。


文章转载自:

http://OE8JsCbt.wtrjq.cn
http://sf8mNO52.wtrjq.cn
http://xFUxZZ4e.wtrjq.cn
http://QcUh6dT9.wtrjq.cn
http://kuOPDPCS.wtrjq.cn
http://ymndervT.wtrjq.cn
http://4BOuRBKB.wtrjq.cn
http://sayj3U93.wtrjq.cn
http://LCkr1mUw.wtrjq.cn
http://Enl7esHk.wtrjq.cn
http://HoRXOiKF.wtrjq.cn
http://Chn5I7yc.wtrjq.cn
http://LXUFAfrf.wtrjq.cn
http://LGT9yfhJ.wtrjq.cn
http://wHF2MEpg.wtrjq.cn
http://pLVtpPMp.wtrjq.cn
http://QtqeubRH.wtrjq.cn
http://8WjrTfcg.wtrjq.cn
http://foVWoXUO.wtrjq.cn
http://HvMr36fv.wtrjq.cn
http://TxKXkqzl.wtrjq.cn
http://wH4DRwdj.wtrjq.cn
http://4UjRVPTa.wtrjq.cn
http://sKjQVPqh.wtrjq.cn
http://dJK49JCg.wtrjq.cn
http://CWwoajSo.wtrjq.cn
http://xmF9Pmsi.wtrjq.cn
http://Kf7OjJm4.wtrjq.cn
http://ph2eybda.wtrjq.cn
http://mhkfVkAo.wtrjq.cn
http://www.dtcms.com/a/380903.html

相关文章:

  • 【Vue2 ✨】Vue2 入门之旅 · 进阶篇(六):keep-alive 与缓存机制
  • IDA pro 生成idapro.hexlic
  • 【CE】CE教程Tutorial:进阶篇(第8关:多级指针)(Pointer Scan工具)
  • Java 更改 Word 文档中文本颜色
  • Cesium 无人机航线规划(环点航线)
  • 一般软件加载显示图片的流程
  • 第十四届蓝桥杯青少组C++选拔赛[2023.1.15]第二部分编程题(3、寻找花坛)
  • Spring Boot中Filter与Interceptor的区别
  • 生产常见问题
  • Linux copy_from_user
  • 数据库:mysqld服务器启动参数大全
  • STM32之RTC
  • 正式工作一年半了 小记一下
  • HDFS与Yarn深入剖析
  • 空间信息与数字技术和传统GIS专业有何不同?
  • 企业内训|智能驾驶案例及实践——某央企汽车集团
  • 告别繁琐配置!Retrofit-Spring-Boot-Starter让HTTP调用更优雅
  • 星座SAR动目标检测(GMTI)
  • Python异常处理自定义:从基础到高级的完整指南
  • R语言水文、水环境模型优化:从最速上升法、岭分析到贝叶斯优化与异方差处理,涵盖采样设计、代理模型与快速率定等
  • PHP启动报错:liboing.so.5:cannot op如何处理?
  • 双碳目标下DNDC模型建模方法及在土壤碳储量、温室气体排放、农田减排、土地变化、气候变化中的应用
  • 半导体常见分析设备之EDX分析
  • 金蝶云星空 × 飞书审批全场景对接案例分享
  • 网易伏羲亮相Arm Unlocked 2025,携手Arm探索中国人工智能创新之路
  • [code-review] docs | GitHub Actions运行器 | workflows/cr.yml
  • 推箱子(Num014)
  • GitHub热榜项目 - 日榜之应用场景与未来发展趋势
  • Redis哈希(Hash):适合存储对象的数据结构,优势与坑点解析
  • docker一次性清理掉所有容器和镜像