为何在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.
相关产品推荐
相关产品推荐

