垃圾回收算法:标记清除法(Mark-Sweep Algorithm)的 Java代码实现

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

标记-清除算法(Mark-Sweep Algorithm)的 Java 实现

标记-清除算法是垃圾回收(Garbage Collection, GC)中的一种经典算法。它的核心思想是通过两个阶段来回收内存:

  1. 标记阶段:从根对象(如栈、静态变量等)出发,标记所有可达对象。

  2. 清除阶段:遍历整个堆内存,回收未被标记的对象(即不可达对象)。

下面我们用 Java 代码来模拟标记-清除算法的流程。


1. 定义对象模型

我们用一个简单的 Object 类来表示堆中的对象,每个对象可以引用其他对象。

class Object {
    String name;
    Object reference; // 引用其他对象
    boolean marked = false; // 标记是否可达

    public Object(String name) {
        this.name = name;
    }

    public void setReference(Object reference) {
        this.reference = reference;
    }
}

2. 模拟堆内存

用一个列表来模拟堆内存,存储所有对象。

import java.util.ArrayList;
import java.util.List;

class Heap {
    List<Object> objects = new ArrayList<>();

    public void add(Object obj) {
        objects.add(obj);
    }

    public List<Object> getObjects() {
        return objects;
    }
}

3. 标记阶段

从根对象出发,递归标记所有可达对象。

class Marker {
    public void mark(Object obj) {
        if (obj == null || obj.marked) {
            return;
        }
        obj.marked = true; // 标记对象为可达
        mark(obj.reference); // 递归标记引用的对象
    }
}

4. 清除阶段

遍历堆内存,回收未被标记的对象。

class Sweeper {
    public void sweep(Heap heap) {
        List<Object> objects = heap.getObjects();
        for (int i = 0; i < objects.size(); i++) {
            Object obj = objects.get(i);
            if (!obj.marked) {
                System.out.println("Sweeping object: " + obj.name);
                objects.remove(i); // 回收对象
                i--; // 调整索引
            } else {
                obj.marked = false; // 重置标记,为下一次 GC 做准备
            }
        }
    }
}

5. 模拟垃圾回收

将上述步骤组合起来,模拟一次完整的垃圾回收。

public class MarkSweepGC {
    public static void main(String[] args) {
        // 创建堆内存
        Heap heap = new Heap();

        // 创建对象
        Object obj1 = new Object("Object1");
        Object obj2 = new Object("Object2");
        Object obj3 = new Object("Object3");
        Object obj4 = new Object("Object4");

        // 设置对象引用关系
        obj1.setReference(obj2);
        obj2.setReference(obj3);
        // obj4 是孤立的,不可达

        // 将对象添加到堆中
        heap.add(obj1);
        heap.add(obj2);
        heap.add(obj3);
        heap.add(obj4);

        // 标记阶段
        Marker marker = new Marker();
        marker.mark(obj1); // 从根对象 obj1 开始标记

        // 清除阶段
        Sweeper sweeper = new Sweeper();
        sweeper.sweep(heap);

        // 打印堆中剩余的对象
        System.out.println("Objects in heap after GC:");
        for (Object obj : heap.getObjects()) {
            System.out.println(obj.name);
        }
    }
}

代码运行结果

假设堆中有以下对象:

  • obj1 -> obj2 -> obj3(可达)

  • obj4(不可达)

运行上述代码后,输出如下:

Sweeping object: Object4
Objects in heap after GC:
Object1
Object2
Object3
  • obj4 被回收,因为它不可达。

  • obj1obj2 和 obj3 仍然存在于堆中。


代码解释

  1. 对象模型

    • Object 类表示堆中的对象,包含一个 reference 字段指向其他对象。

    • marked 字段用于标记对象是否可达。

  2. 堆内存

    • Heap 类模拟堆内存,使用 List<Object> 存储所有对象。

  3. 标记阶段

    • 从根对象(如 obj1)出发,递归标记所有可达对象。

  4. 清除阶段

    • 遍历堆内存,回收未被标记的对象。

    • 重置已标记对象的 marked 字段,为下一次 GC 做准备。

  5. 模拟垃圾回收

    • 创建对象并设置引用关系。

    • 执行标记和清除阶段,回收不可达对象。


标记-清除算法的优缺点

优点:

  • 简单直观,容易实现。

  • 不需要移动对象,适合处理大对象。

缺点:

  • 会产生内存碎片。

  • 清除阶段需要遍历整个堆内存,效率较低。


总结

通过上述 Java 代码,我们模拟了标记-清除算法的流程:

  1. 从根对象出发,标记所有可达对象。

  2. 遍历堆内存,回收未被标记的对象。

标记-清除算法是垃圾回收的基础算法之一,虽然简单,但在实际应用中可能会产生内存碎片问题。现代垃圾回收器(如 JVM 中的 CMS、G1 等)通常会结合其他算法(如标记-整理、分代回收)来优化性能。

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

healthLau

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值