GC算法实践(二) 对象标记、复制算法

本文主要探讨GC算法中的标记和复制算法。介绍了根对象的概念,详细阐述了标记-清除算法的工作原理及其内存碎片问题,然后重点讲解了复制算法,包括其思想、实现方式以及测试验证。通过实例展示了如何正确标记活动对象并实施复制,确保内存的有效管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇文章中,我们实现了自定义分配内存,有了这个基础,我们可以开发垃圾回收算法了。GC算法有很多种,如引用计数法、标记-清除算法、复制算法、分代回收算法等,也有综合运用几种算法的。PHP用到了引用计数算法,Java用到了复制算法和分代回收算法。由于引用计数算法需要频繁更新引用计数,目前暂不研究;标记-清除算法则因为清除后造成大量内存碎片不好管理,目前只研究标记(标记出活动对象);复制算法是本篇研究的重点。

1.标记-清除算法、复制算法简介

1.1 根对象

首先需要理解一个基本概念:根对象。根对象是程序中可以直接访问到的对象,比如:

有两个对象aa有成员b,访问对象a直接用a就行,而访问对象b需要通过a->b,那么对象a就是根对象,对象b由于只能通过a->b来访问,所以不是根对象。

根对象可以是全局变量、函数调用栈上的变量等。

1.2 标记-清除算法

标记-清除算法的大致思想如下:

标记阶段:遍历根对象及其引用的对象。假设每个对象都有个标记位flag,对根对象集合中的每个根对象,从根对象出发,对可以访问到的每个对象的标记位flag设为1(活动对象)。

清除阶段:遍历堆,将非活动对象所占空间设为可用。遍历堆,将标记位flag等于0的对象(即垃圾)所占据的空间设为可用。

标记-清除算法的清除阶段 后,产生很多内存碎片,管理比较麻烦。

1.3 复制算法

复制算法的大致思想如下:

把给对象分配内存的堆(heap)分成大小相等的两部分,或者申请2块大小相同的堆,其中一个堆称为From空间,另一个称为To空间

首次给对象分配内存时,活动堆为From空间,从From空间分配;触发GC时,采用标记-清除算法中的标记算法遍历活动对象,把活动对象复制到To空间,然后就把To空间当做当前活动堆。To空间满触发GC时,把活动对象复制到From空间,如此交替进行。

复制算法的缺点是内存空间利用效率低,只有50%。

2.标记对象

先构建一个测试场景,代码如下:

Object *root[2]; // simulate root objects collection

void test_alloc_memory() {
    Object *objects[6];
    int obj_len[6] = {
  3,2,4,2,3,2};
    int i;

    for(i=0; i<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值