垃圾回收算法有哪些

垃圾回收算法有哪些?能简单介绍一下各自的核心逻辑吗?

垃圾回收算法是 JVM 回收垃圾对象的"核心策略",核心有 4 类基础算法 + 1 类组合策略(分代回收),它们的设计都是围绕"高效识别垃圾、回收内存、减少影响"展开的。

一、核心基础算法(4 类)

1. 复制算法(Copying GC)
  • 核心原理:把内存分成两块大小相等的区域(A 区、B 区),只在 A 区分配对象;GC 时,找出 A 区所有存活对象,复制到 B 区并紧凑排列,然后清空 A 区,下次分配切换到 A 区(循环往复)。
  • 优点:回收速度快(只复制存活对象,不用扫描垃圾);回收后无内存碎片(对象紧凑排列)。
  • 缺点:内存利用率低(只能用一半内存);存活对象多的时候,复制成本高(要拷贝大量对象)。
  • 适用场景:年轻代(比如 Eden + Survivor 区)------ 年轻代对象"朝生夕死",存活比例极低,复制成本低,刚好适配算法优势。
2. 标记-清除算法(Mark-Sweep)
  • 核心原理:分两步走:① 标记:从 GC Roots 出发,遍历所有对象,给存活对象打标记;② 清除:遍历整个内存,把没打标记的垃圾对象回收,释放内存。
  • 优点:内存利用率高(不用拆分内存,全量使用);不用移动对象(减少 CPU 开销)。
  • 缺点:回收后产生大量内存碎片(垃圾对象零散分布,释放后留下零散空闲块);效率受对象总数影响(要遍历所有对象,不管存活还是垃圾)。
  • 适用场景:老年代日常回收------ 老年代对象存活比例高,标记存活对象比扫描垃圾快,且不用移动对象,适合频繁触发的回收。
3. 标记-整理算法(Mark-Compact)
  • 核心原理:在"标记-清除"基础上多一步"整理":① 标记(和标记-清除一致);② 整理:把所有存活对象向内存一端移动,紧凑排列;③ 清除:清空内存另一端的垃圾对象,释放连续空闲空间。
  • 优点:无内存碎片(对象紧凑排列);内存利用率高(全量使用内存)。
  • 缺点:效率比标记-清除低(多了"移动对象"的步骤,还要更新对象引用地址);STW 停顿时间更长。
  • 适用场景:老年代碎片较多时------ 比如多次标记-清除后,内存碎片积累,需要用它整理内存,保证大对象能顺利分配。
4. 标记- sweep - compact 混合算法(Mark-Sweep-Compact)
  • 核心原理:不是独立算法,而是"标记-清除"和"标记-整理"的结合:日常用标记-清除保证回收效率,当内存碎片达到阈值(比如大对象分配失败),触发一次标记-整理清理碎片。
  • 优点:兼顾效率和内存利用率(日常快,碎片多了再整理)。
  • 缺点:逻辑更复杂(要判断碎片阈值)。
  • 适用场景:老年代主流策略------ 比如 CMS 回收器的"并发标记清除"+ 定期"标记整理",就是这种混合思路。

二、组合策略:分代回收算法(Generational GC)

  • 核心原理:不是独立算法,而是"根据对象生命周期划分内存区域,适配不同基础算法"的策略------ 年轻代用复制算法,老年代用标记-清除/标记-整理算法(混合)。
  • 设计依据:对象生命周期有明显差异(大部分对象短寿,少数对象长寿),针对性选择算法能最大化效率。
  • 优点:兼顾年轻代"快速回收"和老年代"高内存利用率",是目前最成熟的 GC 策略。
  • 适用场景:绝大多数 JVM 场景(比如 JDK 8 的 ParNew+CMS、Parallel Scavenge+Parallel Old,都是分代回收)。

三、补充:不分代算法的核心思路(简单提一句)

现在还有打破分代模型的算法(比如 G1、ZGC 用的"区域化回收"),核心是把堆分成多个小 Region,每个 Region 独立回收,按需触发"复制"或"整理",本质是"基础算法的区域化应用",目的是减少 STW 停顿,适配大堆内存(比如 TB 级)。

总结

核心可以概括为:基础算法是"工具",分代回收是"策略"------ 复制算法快、无碎片但费内存(适合年轻代);标记-清除高效但有碎片(适合老年代日常);标记-整理无碎片但慢(适合老年代碎片清理);分代回收则是把这些工具组合起来,适配不同区域的对象特性,实现整体 GC 最优。

相关推荐
君顾19 分钟前
从0到1课后辅导管理系统开发实战:需求文档、架构设计全复盘
java·开发语言
NeoGressAI外贸数字化15 分钟前
外贸建站:新手怎么自建独立站完整指南
java·人工智能
前端 贾公子16 分钟前
第09章:上下文与记忆 (4)
java·服务器·前端
wjjzhbb29 分钟前
中小团队敏捷转型:Scrum还是看板?
java·maven·scrum
GodSure091438 分钟前
Java单一职责原则SRP详解
java·python·单一职责原则
探数API小喇叭43 分钟前
基站查询 API 怎么用?LAC、CELLID 参数详解与实战】
java·开发语言·api·基站定位
catino44 分钟前
spring-IOC、DI
java·spring·rpc
xcl09251 小时前
宠物救助领养系统实战开发指南:从需求分析到部署上线
java·mfc·宠物