垃圾回收算法有哪些

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

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

相关推荐
皮皮林5517 小时前
Java性能调优黑科技!1行代码实现毫秒级耗时追踪,效率飙升300%!
java
冰_河8 小时前
QPS从300到3100:我靠一行代码让接口性能暴涨10倍,系统性能原地起飞!!
java·后端·性能优化
桦说编程10 小时前
从 ForkJoinPool 的 Compensate 看并发框架的线程补偿思想
java·后端·源码阅读
躺平大鹅12 小时前
Java面向对象入门(类与对象,新手秒懂)
java
初次攀爬者13 小时前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq
花花无缺13 小时前
搞懂@Autowired 与@Resuorce
java·spring boot·后端
Derek_Smart14 小时前
从一次 OOM 事故说起:打造生产级的 JVM 健康检查组件
java·jvm·spring boot
NE_STOP15 小时前
MyBatis-mybatis入门与增删改查
java
孟陬19 小时前
国外技术周刊 #1:Paul Graham 重新分享最受欢迎的文章《创作者的品味》、本周被划线最多 YouTube《如何在 19 分钟内学会 AI》、为何我不
java·前端·后端