You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言如何获取所有堆内存分配记录以实现mark-sweep垃圾回收器

C语言自研标记清除GC的堆分配记录实现方案

首选方案:封装标准内存分配接口(教学场景最优)

教学场景下完全不需要考虑复杂的系统级堆结构读取,封装分配接口的方案足够满足演示需求,实现成本极低
你可以自定义一套内存分配/释放函数,替换项目内所有标准库malloc/calloc/realloc/free调用,所有分配的堆块信息会自动存入你维护的全局链表中,示例实现如下:

// 堆分配记录节点,内置标记位可直接用于后续标记阶段
typedef struct gc_alloc_node {
    void* ptr;          // 分配的堆内存起始地址
    size_t size;        // 堆块大小
    unsigned char marked; // 标记清除用的标记位
    struct gc_alloc_node* next;
} gc_alloc_node;

// 全局的堆分配记录链表头
static gc_alloc_node* gc_alloc_list = NULL;

// 封装后的malloc函数
void* gc_malloc(size_t size) {
    void* raw_ptr = malloc(size);
    if (!raw_ptr) return NULL;

    // 新建分配记录节点插入链表头部
    gc_alloc_node* node = malloc(sizeof(gc_alloc_node));
    node->ptr = raw_ptr;
    node->size = size;
    node->marked = 0;
    node->next = gc_alloc_list;
    gc_alloc_list = node;

    return raw_ptr;
}

// 封装后的free函数
void gc_free(void* ptr) {
    gc_alloc_node** prev = &gc_alloc_list;
    gc_alloc_node* curr = gc_alloc_list;
    while (curr) {
        if (curr->ptr == ptr) {
            *prev = curr->next;
            free(curr->ptr);
            free(curr);
            return;
        }
        prev = &curr->next;
        curr = curr->next;
    }
    // 未匹配到分配记录则判定为非法释放,教学场景直接报错终止即可
    fprintf(stderr, "gc_free: invalid pointer %p\n", ptr);
    abort();
}

注意事项:

  • 整个项目所有堆内存操作必须调用你封装的gc_前缀函数,不能直接调用标准库分配接口,否则会遗漏分配记录
  • 后续标记清除逻辑可以直接遍历gc_alloc_list链表,不需要再额外获取堆分配信息

备选方案:Hook系统分配接口(适配已有代码)

如果你的GC需要适配已完成的C代码,不想修改所有内存分配调用,可以通过Hook方式拦截标准库的内存分配调用:

  • Linux平台可通过LD_PRELOAD加载自定义动态库,替换glibc的malloc/free等函数实现
  • Windows平台可通过IAT Hook、Inline Hook拦截系统内存分配函数
  • 该方案兼容性更强但实现复杂度更高,没有旧代码适配需求的教学项目不建议选择

标记清除逻辑对接说明

拿到完整的分配记录链表后,可按标准流程实现标记清除:

  1. 标记阶段:遍历所有GC根(栈变量、全局变量、静态变量存储的指针),如果指针指向分配记录内的堆块,就将对应节点的marked位置为1
  2. 清除阶段:遍历整个gc_alloc_list链表,释放所有marked位为0的堆块和对应节点,同时将剩余节点的marked位重置为0,等待下一轮GC触发

内容的提问来源于stack exchange,提问作者procoder35

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 18:36:05