当前位置: 首页 > news >正文

深入理解垃圾收集算法:从分代理论到经典回收策略

垃圾收集(Garbage Collection, GC)是现代虚拟机自动内存管理的核心机制。它不仅能自动回收不再使用的对象,还能极大减轻开发者在内存管理上的负担。本文将详细讲解垃圾收集算法的基本思想、分代收集理论以及几种经典的垃圾收集算法。

注: 由于各个平台的虚拟机在操作内存方面存在差异,暂不探讨各平台的具体实现细节。


一、垃圾收集算法的基本分类

从判定对象是否消亡的角度出发,垃圾收集算法主要可分为两大类:

  • 引用计数式垃圾收集(Reference Counting GC):直接在对象中维护一个引用计数器,每当有新的引用出现时加一,引用失效时减一。当计数器为0时认为该对象不再使用。然而,由于循环引用的问题,引用计数算法在主流 JVM 中并未使用。

  • 追踪式垃圾收集(Tracing GC):也称为“间接垃圾收集”,它通过从一组特殊的对象(GC Roots)开始,遍历引用链来判定对象是否可达。不可达的对象会被回收。本文介绍的所有算法均属于这一类。


二、分代收集理论:经验法则与内存划分

当前主流的 Java 虚拟机(如 HotSpot、OpenJ9 等)都采用了分代收集理论来设计垃圾收集器。分代收集理论并非严苛的数学定理,而是总结了大量程序运行数据后得到的经验法则,其基本思想基于以下三个假说:

1. 弱分代假说(Weak Generational Hypothesis)

  • 核心观点:绝大多数对象都是“朝生夕灭”的——例如方法内的临时变量、局部对象等,这些对象只存在极短的生命周期。

  • 实践意义:垃圾收集器可以设计出高频、低成本的回收策略,专门针对这些短命对象。

2. 强分代假说(Strong Generational Hypothesis)

  • 核心观点:熬过多次垃圾收集的对象往往具有较长的生命周期,即它们越难以消亡。

  • 实践意义:对于长生命周期的对象,回收的频率可以降低,以减少不必要的回收开销。

3. 跨代引用假说(Intergenerational Reference Hypothesis)

  • 核心观点:跨代引用(如老年代对象引用新生代对象)相对较少。换句话说,绝大部分对象引用发生在同一代中。

  • 实践意义:这使得在进行新生代垃圾收集(Minor GC)时,不必遍历整个老年代,而只需维护一个全局数据结构——记忆集(Remembered Set),记录那些存在跨代引用的内存块,从而显著降低回收时的扫描范围和性能开销。

Java 堆的区域划分

基于上述假说,JVM 通常将 Java 堆划分为以下几个区域:

  • 新生代(Young Generation)

    • Eden 区:新对象的主要分配区域,占大部分新生代空间(通常约80%)。

    • Survivor 区:用于存放经历一次或多次 Minor GC 后仍然存活的对象,通常分为两个区域(From 和 To,各占约10%)。

    • 特点:新生代回收频率高,大量对象在第一轮 GC 后被回收,存活对象则被复制到 Survivor 区,之后有可能晋升到老年代。

  • 老年代(Old Generation)

    • 存放经过多次 GC 后依然存活的对象,主要包括长生命周期的对象,如缓存、静态数据等。

    • 特点:回收频率较低,但每次回收可能需要处理更多的对象和更高的内存占用。

  • 其他区域:例如方法区(包含运行时常量池、类的元数据等)以及直接内存(不在 JVM 管理内存内,但用于高性能 I/O)。


三、经典垃圾收集算法

在追踪式垃圾收集范畴中,几种经典的垃圾收集算法各有侧重,它们通常以标记阶段为基础,不同之处在于如何回收垃圾对象和处理存活对象。

3.1 标记-清除算法(Mark-Sweep)

工作原理
  1. 标记阶段:从 GC Roots 开始,遍历所有可达对象,并对其做上标记。

  2. 清除阶段:扫描整个堆,回收所有未被标记的对象。

优缺点
  • 优点:实现简单,无需移动存活对象。

  • 缺点

    • 执行效率不稳定:当堆中大量对象需要回收时,标记和清除的操作会耗费较长时间。

    • 内存碎片化:清除后的堆内存可能分布不连续,导致后续大对象分配困难,可能引发额外的垃圾回收。

适用场景
  • CMS(Concurrent Mark Sweep)收集器的老年代回收往往采用标记-清除算法,但会结合碎片整理技术以应对碎片化问题。


3.2 标记-复制算法(Mark-Copy)

工作原理
  • 半区复制:将可用内存划分为两块(称为半区),一次只使用其中的一块。当这一块内存填满时,将存活对象复制到另一块内存上,然后清空当前区。

优点
  • 无碎片问题:复制过程中存活对象连续存放,内存分配更高效。

  • 顺序分配:复制后的内存空间是连续的,新对象可以顺序分配。

缺点
  • 空间浪费:因为每次只能使用一半的内存,内存利用率较低。

  • 复制开销:当存活对象较多时,复制的成本会急剧增加。

优化策略:Appel式回收
  • 内存布局优化:将新生代划分为一块较大的 Eden 区和两个较小的 Survivor 区,常见比例为 8:1:1(即 Eden 占80%,每个 Survivor 占10%)。

  • 分配担保:在发生 Minor GC 时,将 Eden 和一个 Survivor 中存活的对象复制到另一个 Survivor 区;若 Survivor 空间不足,则将对象直接晋升到老年代。这样设计既减少了复制负担,也为极端情况下的对象存活提供了安全保证。

适用场景
  • Serial、ParNew 等新生代收集器普遍采用标记-复制算法,因新生代中的对象大多数都能在第一轮 GC 中被回收。


3.3 标记-整理算法(Mark-Compact)

工作原理
  1. 标记阶段:与标记-清除算法类似,对存活对象进行标记。

  2. 整理阶段:将所有存活对象向内存的一端移动,形成一块连续的内存区域,然后清理掉移动后剩余的内存碎片。

优缺点
  • 优点:消除了内存碎片问题,便于后续大对象的分配。

  • 缺点

    • 移动开销大:移动对象需要更新所有对该对象的引用,这个过程非常消耗时间。

    • 停顿时间长:对象移动通常要求暂停所有用户线程(即“Stop The World”),这会对响应时间产生较大影响。

适用场景
  • 老年代垃圾收集往往使用标记-整理算法,因为老年代中的对象大部分存活,移动它们可以确保内存连续性,提升整体吞吐量。例如,HotSpot 中关注吞吐量的 Parallel Scavenge 收集器就采用了基于标记-整理算法的策略,而 CMS 则采用标记-清除算法以降低停顿时间。

折中方案
  • 有些垃圾收集器采用混合策略:平时使用标记-清除算法,容忍一定的内存碎片;当碎片化严重影响内存分配时,再采用标记-整理算法进行一次全堆整理,CMS就是采用这种方法。现代一些收集器(如 ZGC、Shenandoah)利用读屏障技术,实现整理过程与用户线程并发执行,降低停顿时间。


四、垃圾收集类型概览

为了应对不同场景和内存区域,垃圾收集器通常根据收集范围将 GC 分为以下几种类型:

类型范围触发条件典型收集器
Minor GC新生代Eden 区填满Serial、ParNew
Major GC老年代老年代空间不足CMS(仅老年代回收)
Mixed GC新生代 + 部分老年代针对 G1 等收集器的 Region 回收G1 收集器
Full GC整个堆及方法区空间分配失败或手动触发所有收集器(最终回收)

说明:不同收集器对 GC 类型的定义可能略有不同,需结合具体文档理解。


五、总结

  • 分代收集理论奠定了现代垃圾收集器的设计基础,通过将堆划分为新生代和老年代,实现了针对不同对象生命周期的“对症下药”。

  • 各类垃圾收集算法(标记-清除、标记-复制、标记-整理)各有优缺点,设计者往往需要在停顿时间、内存利用率、吞吐量之间做权衡。

  • 未来趋势:随着硬件技术和应用需求的发展,诸如 ZGC、Shenandoah 等新一代垃圾收集器正尝试在全区域收集模式下实现更低延迟和更高吞吐量,这将对传统分代模型提出挑战或改进。

相关文章:

  • 全球变暖
  • 答疑解惑:EMC VMAX3 MMCS控制台不定期重启原因分析
  • 浙大:DeepSeek技术溯源及前沿探索
  • 在SpringBoot中整合Mybatis框架
  • 实现极限网关(INFINI Gateway)配置动态加载
  • H2S Probe硫化氢荧光探针它可以通过荧光来检测H2S水平
  • Vue如何利用Postman和Axios制作小米商城购物车----简版
  • 在MFC中使用Qt(二):实现Qt文件的自动编译流程
  • 虚拟机Vmware无法连接网络
  • FFmpeg开发学习:AVFormatContext结构体
  • 【大模型基础_毛玉仁】3.4 Prompt 技巧
  • 深度学习四大核心架构:神经网络(NN)、卷积神经网络(CNN)、循环神经网络(RNN)与Transformer全概述
  • C++的IO流
  • hackmyvm-jan
  • 如何在 React 项目中使用React.lazy和Suspense实现组件的懒加载?
  • Linux进程间的通信
  • 如何将3DMax模型转换到Blender?
  • 51单片机
  • 基于代理(http\https\socks)的网络访问逻辑重定义
  • 基于本人的专利设计三角形式的三组定子和中间的分形转子结构
  • 回家了!子弹库帛书二、三卷将于7月首次面向公众展出
  • 光速晋级!2025年多哈世乒赛孙颖莎4比0战胜对手
  • 中国进出口银行:1-4月投放制造业中长期贷款超1800亿元
  • “家国万里时光故事会” 举行,多家庭共话家风与家国情怀
  • 人民日报整版聚焦:外贸产品拓内销提速增量,多地加快推动内外贸一体化
  • 今年有望投产里程已近3000公里,高铁冲刺谁在“狂飙”?