为什么不调用free()会减小堆的大小?

时间:2011-06-17 15:18:27

标签: c memory-management

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

3 个答案:

答案 0 :(得分:6)

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

可以通过使用否定参数调用sbrk缩小堆,但我怀疑未完成的主要原因是因为进程可能在某个时候需要再次使用内存。当底层内存发生变化时,调整malloc竞技场可能需要一些时间。

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

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

并想一想额外负载会有多么低效。

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

当然,这一切都假设malloc完全使用sbrk。由于逻辑和物理内存之间的脱节,现代操作系统可能提供更好的替代方案。

答案 1 :(得分:1)

当你要求记忆时(例如使用malloc),它有两个选择:

  • 如果它已经有足够的空间“保留”它只是给你那个记忆
  • 如果没有,请求操作系统(使用系统调用)

当你free内存时,相同的机制会保留它,以防你以后要求它。通过要求记忆/放弃记忆不断打扰操作系统效率不高。

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

答案 2 :(得分:0)

一般来说,这些日子首先使用sbrk()并没有多大意义。有关该功能的更深入讨论,请参阅this question