C 为什么';调用free()来减少堆的大小吗?

C 为什么';调用free()来减少堆的大小吗?,c,memory-management,C,Memory Management,我们知道程序的堆栈在运行时会增长或收缩。在C程序中,当我们使用malloc()分配内存时,如果当前内存不足,它将调用sbrk()来扩展堆大小。当我们使用free()释放分配的内存时,它不会收缩堆。为什么收缩堆没有意义?堆栈不会收缩。堆栈的使用可能是可变的,但堆栈本身的大小通常保持不变 您可以通过使用一个否定参数调用sbrk来收缩堆,但我怀疑没有这样做的主要原因是进程可能在某个时候再次需要内存。当底层内存发生变化时,调整mallocarena可能需要一些时间 当你需要更多的内存时,没关系,你付出代

我们知道程序的堆栈在运行时会增长或收缩。在C程序中,当我们使用
malloc()
分配内存时,如果当前内存不足,它将调用
sbrk()
来扩展堆大小。当我们使用
free()
释放分配的内存时,它不会收缩堆。为什么收缩堆没有意义?

堆栈不会收缩。堆栈的使用可能是可变的,但堆栈本身的大小通常保持不变

您可以通过使用一个否定参数调用
sbrk
来收缩堆,但我怀疑没有这样做的主要原因是进程可能在某个时候再次需要内存。当底层内存发生变化时,调整
malloc
arena可能需要一些时间

当你需要更多的内存时,没关系,你付出代价是因为你想要一些东西。但在释放内存时,您不想为此付出代价,因为您不需要这样做。而且,如果你真的这样做了,那么再次需要记忆,你将不断付出代价。想想这个循环:

for (int i = 0; i < 1000; i++) {
    char *m = malloc (1000000);
    free (m);
}
for(int i=0;i<1000;i++){
char*m=malloc(1000000);
自由(m);
}
想想如果有额外的负载,效率会有多低

您可以将已释放但未释放回操作系统的内存视为您自己的个人内存缓存


当然,这都是假设
malloc
使用
sbrk
。由于逻辑内存和物理内存之间的断开连接,现代操作系统可能提供更好的替代方案。

一般来说,现在首先使用
sbrk()
没有多大意义。有关该函数的更深入的讨论,请参见。

当您请求内存时(例如使用
malloc
),它有两种选择:

  • 如果它已经有足够的空间“保留”,它只是给你的记忆
  • 如果没有,它会询问操作系统(使用系统调用)
当你
释放
内存时,同样的机制会保留它,以防你以后需要它。不断地通过请求内存/放弃内存来干扰操作系统是没有效率的


显然,既然您在谈论C,那么值得一提的是,没有任何标准会强制执行任何此类行为。

谢谢。您的意思是堆栈本身是常量,堆栈的使用是可变的。这是空间局部性,我们通常不会收缩内存,因为我们可能再次需要内存(实际上可以通过调用带负参数的sbrk来实现)