我的C程序中的结构上的free()有问题。当我查看/proc//statm在空闲前后的情况时,它似乎并没有减少。在这种情况下,我使用free()是错的,还是读/proc//statm是错的?
下面是一个产生问题的测试用例:
struct mystruct {
unsigned int arr[10000];
};
void mem() {
char buf[30];
snprintf(buf, 30, "/proc/%u/statm", (unsigned)getpid());
FILE* pf = fopen(buf, "r");
if (pf) {
unsigned size; // total program size
unsigned resident;// resident set size
unsigned share;// shared pages
unsigned text;// text (code)
unsigned lib;// library
unsigned data;// data/stack
unsigned dt;// dirty pages (unused in Linux 2.6)
fscanf(pf, "%u %u %u %u %u %u", &size, &resident, &share, &text, &lib, &data);
printf("Memory usage: Data = %d\n", data*sysconf(_SC_PAGESIZE));
}
fclose(pf);
}
int main(int argc, char **argv) {
mem();
struct mystruct *foo = (struct mystruct *)malloc(sizeof(struct mystruct));
mem();
free(foo);
mem();
}
输出为:
Memory usage: Data = 278528
Memory usage: Data = 282624
Memory usage: Data = 282624
当我期望它是:
Memory usage: Data = 278528
Memory usage: Data = 282624
Memory usage: Data = 278528
我用malloc'ing a(char*)做了一个类似的测试,然后释放它,它工作得很好。结构有什么特别的地方吗?
最佳答案
您的答案是right over here on Stack Overflow,但简短的版本是,出于很好的原因,内存分配器不会将内存返回到主机操作系统,而是将其(在程序的数据空间中)作为某种空闲列表保存。
库保存内存的一些原因是:
与内核交互比简单地执行库代码要慢得多
收益很小。大多数程序都有一个稳定的状态或不断增加的内存占用,因此分析堆以寻找可返回内存所花费的时间将完全浪费。
内部碎片化使得页面对齐的块(唯一可以返回内核的东西)不太可能存在,另一个原因是不让程序慢下来寻找不存在的东西。
返回嵌入在空闲块中的页面会将页面两侧块的低部分和高部分分割开来。
少数返回大量内存的程序可能会绕过malloc()并使用mmap(2)简单地分配和释放页面。