垃圾回收算法有哪些

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

垃圾回收算法是 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 最优。

相关推荐
小王师傅662 小时前
【轻松入门SpringBoot】actuator健康检查(上)
java·spring boot·后端
醒过来摸鱼2 小时前
Java classloader
java·开发语言·python
专注于大数据技术栈2 小时前
java学习--StringBuilder
java·学习
loosenivy3 小时前
企业银行账户归属地查询接口如何用Java调用
java·企业银行账户归属地·企业账户查询接口·企业银行账户查询
IT 行者3 小时前
Spring Security 6.x 迁移到 7.0 的完整步骤
java·spring·oauth2
JIngJaneIL3 小时前
基于java+ vue农产投入线上管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
东东的脑洞3 小时前
【面试突击二】JAVA基础知识-volatile、synchronized与ReentrantLock深度对比
java·面试
川贝枇杷膏cbppg3 小时前
Redis 的 AOF
java·数据库·redis
吃喝不愁霸王餐APP开发者4 小时前
Java后端系统对接第三方外卖API时的幂等性设计与重试策略实践
java·开发语言
TG:@yunlaoda360 云老大4 小时前
华为云国际站代理商的CBR主要有什么作用呢?
java·网络·华为云