考虑下面的C代码,它创建10万4KB大小的页面,然后释放99,999页,最后释放最后一页:内存泄漏使用malloc
#include <stdio.h>
#include <stdlib.h>
#define NUM_PAGES 100000
int main() {
void *pages[NUM_PAGES];
int i;
for(i=0; i<NUM_PAGES; i++) {
pages[i] = malloc(4096);
}
printf("%d pages allocated.\n", NUM_PAGES);
getchar();
for(i=0; i<NUM_PAGES-1; i++) {
free(pages[i]);
}
printf("%d pages freed.\n", NUM_PAGES-1);
getchar();
free(pages[NUM_PAGES-1]);
printf("Last page freed.\n");
getchar();
return 0;
}
如果你编译,运行并且监视进程的内存使用情况,可以看到内存使用量在第一个getchar
(内存分配为100,000页时)之前达到了大约400MB,然后即使在99,999页被解除分配后(第二个之后getchar
),最后,当最后一页被解除分配时,它下降到1MB。
所以,我的问题是为什么会发生这种情况?为什么只有当所有页面被释放后,整个内存才会返回到操作系统?有没有任何页面大小或任何页面对齐,防止这种事情发生?我的意思是,当只有一个页面被释放时,是否有任何页面大小或对齐方式让任何mableced页面完全返回到操作系统?
发生这种情况是因为C库使用'sbrk()'动态调整其未初始化数据的大小。它是顺序的,所以只有在最新的分配释放后才能缩小。如果将分配大小增加为131072字节(128k),'strace'表示它使用'mmap()'来代替分配,而每个'free()'实际上将分配返回给操作系统。因此,使用分配缓存,只向OS提出/返回更大的块。 –
@NominalAnimal男人,你救了我的命!非常感谢上面和下面的评论。这正是我期待的答案。如果你已经回答了(没有评论),我会接受你的答案... – LuisABOL