我的测试代码显示,在free()程序退出之后和之前,堆内存都返回给操作系统。我使用htop(与 相同top)来观察行为。我的 glibc 版本是ldd (Ubuntu GLIBC 2.31-0ubuntu9.9) 2.31.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUFSIZE 10737418240
int main(){
printf("start\n");
u_int32_t* p = (u_int32_t*)malloc(BUFSIZE);
if (p == NULL){
printf("alloc 10GB failed\n");
exit(1);
}
memset(p, 0, BUFSIZ);
for(size_t i = 0; i < (BUFSIZE / 4); i++){
p[i] = 10;
}
printf("before free\n");
free(p);
sleep(1000);
printf("exit\n");
}
Run Code Online (Sandbox Code Playgroud)
为什么会出现这个问题为什么 free() 函数不将内存返回给操作系统?观察到与我相反的行为?OP也使用linux,问题是在2018年提出的。我错过了什么吗?
Linux 以不同的方式对待大于的分配MMAP_THRESHOLD。请参阅为什么 malloc 从某个阈值开始依赖 mmap?
您链接的问题(其中分配可能不会立即完全回收)使用小型分配,这些分配在每次小型释放时都会汇集在一起,并且malloc()不会立即返回到操作系统(这会很慢)。您的单个巨大分配肯定会经过该mmap()路径,因此完全独立的分配将被完全且立即回收。
可以这样想:如果你要求某人给你买鸡蛋和牛奶,他们很可能会只去一次,然后带着你要求的东西回来。但如果你要鸡蛋和钻戒,他们会将它们视为两个完全不同的请求,并使用截然不同的策略来满足。如果您随后说您不再需要鸡蛋和戒指,他们可能会保留鸡蛋以供饥饿时使用,但他们可能会立即尝试收回购买戒指的钱。