为什么 C 管理堆,而不是操作系统?

Why does C manage the heap, instead of the operating system?

换句话说,为什么 free() 不只是 return 操作系统的内存,而 malloc 只是向操作系统请求内存?

这解压为三个密切相关的问题:

  1. malloc 本身就是一个 C 方法。您正在使用为您提供它的标准库,但最终,它就像您的一样是 C 代码。
  2. 在某些操作系统中,您只能从 OS 大小的页面中获取内存(使用 mmap)。这对于您的常规数据结构来说太大了。
  3. 每次需要内存时都进行系统调用太昂贵了。

Why does C need to manage its own heap?

实际上并没有指定它需要,但它需要按照标准中描述的方式实现 malloc() 和朋友。因此,如果 一个 OS 已经提供了这样的接口,则 C 实现可以只提供一个小的包装器。

Is it because the OS will only allow you to allocate and free contiguous memory of a minimum size? And if that's true, what's the reason?

是的。一个典型的 OS 将管理 paged 内存和映射或取消映射处理整页内存。 可以为"paged"的内存单元取决于硬件架构。您可能想阅读有关 memory management units (MMU) 工作原理的一些详细信息。在没有 MMU 的体系结构上,操作系统可能不会做 任何事情,C 实现只会从物理地址 space 中的固定位置满足 malloc() 请求。

其实留给实现。问题:

why doesn't free() just return the memory to the operating system, and malloc simply request memory from the operating system?

是错误的,因为没有什么能阻止实施。所以这个问题没有答案——每个实现都可能不同(它只需要符合标准)

Why does C need to manage its own heap? (Is it because the OS will only allow you to allocate and free contiguous memory of a minimum size?)

操作系统以页为单位管理内存。分配和释放页面的开销很高。 C 中的大多数分配往往比页面大小小得多。

根据其他答案,这是我收集的答案。

大多数操作系统只将内存分配给固定大小的进程,称为页面。当一个进程 return 的内存到 OS 时,它只能以整页的形式这样做。页是固定大小的内存序列。页面的起点和终点是固定的,所以即使您有足够大的可用内存,您也无法 return 到 OS 除非它介于页面的起点和终点。

另一方面,您可以想象没有操作系统(或者操作系统从它自己的堆中为程序分配内存)。这有助于我更好地理解事情,因为操作系统妨碍了我的直觉,因为它看起来好像释放的内存被丢进了一个黑洞,而分配的内存正从一个类似的黑洞中出来。没有任何OS,计算机中的所有内存都可以被描绘成属于一个大的单元格序列。如果您在计算机中分配所有可用内存,然后开始释放一些内存,那么您可能无法找到足够大的连续内存块来完成 malloc 请求。