2011-06-17 37 views
2

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

回答

6

这个堆栈确实是不是收缩。您的使用的堆栈可能是可变的,但堆栈本身的大小通常保持不变。

可以通过调用sbrk带负参数缩小堆,但我怀疑没有这样做的主要原因是因为该进程可能在某些时候需要再次内存。当底层内存发生变化时,可能需要一些时间来调整malloc竞技场。

当你需要更多的记忆,这很好,你付出代价,因为你想要的东西。但是当你释放内存时你不想支付这个价格,因为你不需要需要。而且,如果你这样做了,那么再次需要这种记忆,你会不断付出代价。想想这个循环:

for (int i = 0; i < 1000; i++) { 
    char *m = malloc (1000000); 
    free (m); 
} 

并且考虑到额外负载会带来多少效率。

您可以将内存释放但不释放回操作系统作为您自己的内存缓存。

这都是假设,当然,malloc根本就使用sbrk。由于逻辑和物理内存之间的断开,现代操作系统可能会提供更好的选择。

+0

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

0

总的来说,最近几天使用sbrk()并没有多大意义。有关该功能的更深入讨论,请参阅this question

1

当你问的内存(使用malloc例如)它有两种选择:

  • 如果它已经有足够的空间“保留”它只是给你内存
  • 如果没有它去,并询问操作系统(使用系统调用)

当你free内存,同样的机制保持它,以防万一你问以后。通过询问内存/放弃内存不断打扰操作系统将不会有效。

很明显,因为你在谈论C,所以值得一提的是没有标准会强制执行任何这样的行为。

相关问题