跳转到内容

垃圾回收算法

来自代码酷

垃圾回收算法(Garbage Collection Algorithms)是Java虚拟机(JVM)中用于自动管理内存的核心机制,通过识别并回收不再使用的对象来释放内存空间。本条目将详细介绍常见的垃圾回收算法、工作原理及其应用场景。

概述[编辑 | 编辑源代码]

在Java等高级语言中,程序员无需手动释放内存,而是由垃圾回收器(Garbage Collector, GC)自动完成。垃圾回收算法的目标是:

  1. 识别哪些对象是“垃圾”(即不再被程序引用)。
  2. 回收垃圾对象占用的内存。
  3. 尽量减少程序停顿时间(Stop-The-World)。

常见垃圾回收算法[编辑 | 编辑源代码]

标记-清除算法(Mark-Sweep)[编辑 | 编辑源代码]

标记-清除是最基础的垃圾回收算法,分为两个阶段: 1. **标记阶段**:从GC Roots(如静态变量、活动线程栈中的引用)出发,遍历所有可达对象并标记为“存活”。 2. **清除阶段**:遍历堆内存,回收未被标记的对象。

特点[编辑 | 编辑源代码]

  • 优点:实现简单,不移动对象。
  • 缺点:产生内存碎片,可能导致后续分配大对象失败。

示例[编辑 | 编辑源代码]

  
public class MarkSweepExample {  
    public static void main(String[] args) {  
        Object obj1 = new Object(); // 对象A  
        Object obj2 = new Object(); // 对象B  
        obj1 = null; // 对象A变为垃圾  
        System.gc(); // 触发垃圾回收(不保证立即执行)  
    }  
}

复制算法(Copying)[编辑 | 编辑源代码]

复制算法将内存分为两块(From空间和To空间),仅使用其中一块。垃圾回收时,将存活对象复制到另一块空间,并清空原空间。

特点[编辑 | 编辑源代码]

  • 优点:无内存碎片,分配高效(通过指针碰撞)。
  • 缺点:内存利用率仅50%。

Mermaid 图示[编辑 | 编辑源代码]

flowchart LR A[From空间: 存活对象 + 垃圾] -->|复制存活对象| B[To空间: 仅存活对象] A -->|清空| C[From空间: 空闲]

标记-整理算法(Mark-Compact)[编辑 | 编辑源代码]

标记-整理结合了标记-清除和复制算法的优点: 1. 标记存活对象。 2. 将存活对象向内存一端移动,消除碎片。

适用场景[编辑 | 编辑源代码]

适合老年代(如CMS的最终回收阶段)。

分代收集算法(Generational)[编辑 | 编辑源代码]

现代JVM普遍采用分代收集,基于对象生命周期将堆划分为:

  • **新生代**(Young Generation):使用复制算法(如Serial、ParNew)。
  • **老年代**(Old Generation):使用标记-清除或标记-整理(如CMS、G1)。

Mermaid 分代模型[编辑 | 编辑源代码]

pie title 堆内存分代 "新生代 (Eden + Survivor)" : 40 "老年代" : 60

实际案例[编辑 | 编辑源代码]

电商系统内存优化[编辑 | 编辑源代码]

某电商平台在高并发场景下频繁触发Full GC,通过以下步骤优化: 1. 使用`-XX:+UseG1GC`启用G1垃圾回收器。 2. 调整新生代与老年代比例(`-XX:NewRatio=2`)。 3. 监控GC日志(`-Xloggc:/path/to/gc.log`)确认效果。

数学基础[编辑 | 编辑源代码]

垃圾回收的停顿时间(Pause Time)可通过以下公式估算: Pause Time=Live DataThroughput+Overhead 其中:

  • *Live Data*:存活对象大小。
  • *Throughput*:回收器处理速度。

总结[编辑 | 编辑源代码]

垃圾回收算法的选择需权衡吞吐量、停顿时间和内存开销。理解这些算法有助于优化JVM参数并解决内存泄漏问题。

模板:Java虚拟机相关