垃圾回收算法详解
最近在准备面试,正把平时积累的笔记、项目中遇到的问题与解决方案、对核心原理的理解,以及高频业务场景的应对策略系统梳理一遍,既能加深记忆,也能让知识体系更扎实,供大家参考,欢迎讨论。
好的 👍 我帮你把这几种 垃圾回收算法(复制、标记清除、标记整理、分代收集)整理成一篇文章,结构清晰,适合学习和写文章引用。
在 Java 虚拟机(JVM)的内存管理中,垃圾回收(Garbage Collection, GC)是保证程序稳定运行的核心机制。其主要目标是回收不再使用的对象所占的内存空间,以便为新对象提供可用内存。常见的垃圾回收算法
包括 复制算法、标记清除、标记整理 以及 分代收集策略。
1. 复制算法(Copying)
适用场景:新生代(Young Generation)
复制算法将内存划分为大小相同的两块,每次仅使用其中的一块。当一块内存用完后,会将仍然存活的对象复制到另一块中,然后一次性清理原内存空间。
-
优点
- 实现简单,效率高
- 内存分配顺序性强,不会产生碎片
-
缺点
- 内存利用率低,仅能使用一半内存
- 如果存活对象过多,复制成本会很高
因此,复制算法更适合 对象生命周期短、死亡率高的新生代,不适合对象存活时间长的老年代。
(图片来源网络)
2. 标记清除算法(Mark-Sweep)
适用场景:早期的老年代回收
该算法分为两个阶段:
- 标记阶段:标记所有需要回收的对象
- 清除阶段:统一回收被标记的对象
-
优点
- 实现相对简单
- 不需要额外的内存空间
-
缺点
- 标记清除算法会产生大量内存碎片,从而影响后续对象分配。比如某个对象需要 连续 6 个内存单元,虽然整体剩余空间足够,但由于不连续,仍可能出现分配失败,被迫触发一次 GC。
- 标记清除算法会产生大量内存碎片,从而影响后续对象分配。比如某个对象需要 连续 6 个内存单元,虽然整体剩余空间足够,但由于不连续,仍可能出现分配失败,被迫触发一次 GC。
3. 标记整理算法(Mark-Compact)
适用场景:老年代(Old Generation)
该算法在标记阶段与“标记-清除”相同,但在清理前会将所有存活对象向一端移动,保证空间的连续性,最后清理边界外的内存
。
-
优点
- 避免了标记清除算法中产生的内存碎片问题
- 分配效率更高,适合大对象的内存分配
-
缺点
- 回收效率比复制算法略低
图解:1.标记阶段 (Mark): 遍历内存,识别并标记所有存活对象(如对象A、C、E)和垃圾对象(如对象B、D、F)。
2.整理阶段 (Compact): 将所有存活对象向内存的一端(通常是左侧)移动,从而压缩它们。
3.清理阶段: 在存活对象区域之后,一次性清理出大块的连续空闲内存,完全避免了内存碎片。
4. 分代收集策略(Generational Collection)
核心思想:分代收集本身不是一种具体算法,而是一种策略。它根据对象生命周期的不同,选择合适的垃圾回收算法来提升效率。
-
新生代(Young Generation)
大量对象很快变为垃圾,适合 复制算法(Copying) -
老年代(Old Generation)
对象存活率高,适合 标记清除 或 标记整理
分代收集算法正是 JVM 主流垃圾回收器的核心思路,通过针对不同特性的对象使用合适的算法,提高整体效率。