垃圾回收算法有哪些

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

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

相关推荐
晨晖21 小时前
MyBatisPlus的条件构造器
java·数据库·windows
有味道的男人1 小时前
速卖通商品详情接口(速卖通API系列)
java·大数据·数据库
DanB241 小时前
Java(网络编程)
java·网络·php
5***84641 小时前
Spring全家桶简介
java·后端·spring
u***1371 小时前
Tomcat的server.xml配置详解
xml·java·tomcat
花阴偷移1 小时前
kotlin语法(上)
android·java·开发语言·kotlin
平原人1 小时前
JVM字节码数据结构总览和读取
jvm·字节码
木易 士心1 小时前
Go、Rust、Kotlin、Python 与 Java 从性能到生态,全面解读五大主流编程语言
java·golang·rust
qq_336313931 小时前
java基础-set系列集合
java·开发语言·python