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

为何在xv6中动态分配内存后进程内存占用与预期不符?

问题描述

在xv6环境下编写了如下测试代码:调用malloc动态分配内存后,通过memsize获取的进程内存占用(对应proc->sz)大幅增长;调用free释放内存后,该值却没有变化。请问该现象的原因是什么?


实现的memsize函数

uint
memsize(void){ // 获取当前进程的内存大小并返回
    uint size;
    struct proc *p;
    p = myproc();
    size = p->sz;
    
    return size;
}

测试代码test_memsize.c

#define SIZE 2048

#include "types.h"
#include "user.h"

int main(void){
    int msize = memsize();
    printf("The process is using %dB\n", msize); // 输出: 12288B
    
    char *tmp = (char *)malloc(SIZE * sizeof(char)); 
    
    printf("Allocating more memory\n");
    msize = memsize();
    printf("The process is using %dB\n", msize); // 输出: 45045B
    
    free(tmp);
    printf("Freeing memory\n");
    msize = memsize();
    printf("The process is using %dB\n", msize); // 输出: 45045B
    
    exit();
}

原因分析
  • proc->sz的定义:xv6中proc->sz代表的是进程虚拟地址空间的总长度,即从进程起始地址到堆顶(end)的地址范围大小,并非进程实际正在使用的内存量。
  • malloc的内存扩展逻辑:xv6的malloc在需要更多内存时,会通过sbrk()系统调用向内核申请扩展虚拟地址空间。由于xv6以4096字节的页为内存管理单位,且sbrk()会一次性扩展多页以减少系统调用开销,所以哪怕只申请2048字节,proc->sz也会跳变到更大的数值。
  • free的内存回收机制:xv6的free仅将释放的内存块标记为可用,归还给用户态的堆空闲链表,不会主动调用sbrk()把内存归还给内核。因此进程的虚拟地址空间大小(proc->sz)不会因为用户态释放内存而缩小,只有进程退出时,内核才会回收整个地址空间。

综上,调用free后proc->sz保持不变,是因为内核并未回收对应的虚拟地址空间,只是用户态内存分配器标记了该块内存可复用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 00:30:55