用mark&sweep回收算法实现个C保守垃圾收集器

注意:本文重点在实现(x86 gcc unix like环境下),不在算法(否则也不用最简单的回收算法),并且纯属教学 (娱乐) 作用,不讲究效率,但求能用即可,也没有继续做到支持多线程。

具体代码放在github上:[https://github.com/Yuandong-Chen/singlethreadGC]

目录:

实现中的重难点介绍:

对外接口部分示意代码:

#include "interface3.h"
#include <...> // 必要头文件

int main()
{
    __gc_init(); /* to init gc */
    /*add some code you like*/
    ...
    /* need some memory in heap */
    void *forgetToFree = (void *)gc_calloc(sizeof(struct XXX));

    /*add some code you like*/
    ...
    __gc_exit(); /* to destroy gc */
    return 0;
}

如何找到mark&sweep的根节点:

i) 对于自动变量的标记,从当前栈顶一直向上找到environ指正位置即可,当然也可以通过在程序中读入/proc/pid/maps 查看栈底地址。 然后,只要把这些区域标记即可。

ii) 对于全局变量的标记,利用链接器变量 _etext, _end标记即可。( 注意 gcc工具是支持的,但是其他编译链接工具完全不能保证 )

iii) 对于临时变量,标记当前寄存器。

具体代码片段:

marksweep.c 文件中:

static unsigned int stack_bottom = 0;
extern char _end[];
extern char _etext[];
extern char** environ;

void gc_collect()
{
    unsigned int stack_top;
    unsigned int _eax_,_ebx_,_ecx_,_edx_,_esi_,_edi_;

    asm volatile ("movl    %%ebp, %0" : "=r" (stack_top));

    asm volatile ("movl    %%eax, %0" : "=r" (_eax_));
    asm volatile ("movl    %%ebx, %0" : "=r" (_ebx_));
    asm volatile ("movl    %%ecx, %0" : "=r" (_ecx_));
    asm volatile ("movl    %%edx, %0" : "=r" (_edx_));
    asm volatile ("movl    %%esi, %0" : "=r" (_esi_));
    asm volatile ("movl    %%edi, %0" : "=r" (_edi_));

/* 我们标记一些寄存器里头的临时变量 */
    mark(_eax_);
    mark(_ebx_);
    mark(_ecx_);
    mark(_edx_);
    mark(_esi_);
    mark(_edi_);

    mark_from_region((ptr *)((char *)stack_top + 4),(ptr *)(stack_bottom)); //我们标记自动变量
    mark_from_region((ptr *)((char *)_etext + 6),(ptr *)(_end)); //我们标记全局变量

    sweep();
}

int __gc_init()
{
    unsigned int stack_top;
    unsigned int curr;
    asm volatile ("movl %%ebp, %0" : "=r" (stack_top));
    curr = stack_top;
    /* 用简单的循环检查出栈底地址(有逻辑漏洞) */
    while(*(unsigned int *)curr != (unsigned
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值