mmap() 相对于 sbrk() 的优势?

Advantages of mmap() over sbrk()?

来自我的书:

Recall from our first discussion that modern dynamic memory managers not only use sbrk() but also mmap(). This process helps reduce the negative effects of memory fragmentation when large blocks of memory are freed but locked by smaller, more recently allocated blocks lying between them and the end of the allocated space. In this case, had the block been allocated with sbrk(), it would have probably remained unused by the system for some time (or at least most of it).

有人可以解释一下使用 mmap 如何减少内存碎片的负面影响吗?给定的例子对我来说没有任何意义,一点也不清楚。


it would have probably remained unused by the system for some time

为什么提出这个要求,当我们释放它时系统可以稍后使用它。也许 OS 在堆中保留已释放块的列表以尽可能使用它们,而不是在堆中使用更多 space。

请联系这两个问题。

当使用sbrk()时,堆就是一个很大的内存块。如果您的分配和释放模式没有留下大的、连续的内存块,那么每次大的分配都需要增加堆。这可能会导致内存使用效率低下,因为所有未使用的间隙都留在堆中。

使用mmap(),你可以拥有一堆独立的映射内存块。因此,您可以将 sbrk() 堆用于小型分配,可以整齐地打包,并使用 mmap() 进行大型分配。当您完成这些大块之一时,您可以删除整个映射。

Advantages of mmap() over sbrk()?

  1. brk/sbrk是后进先出法。假设您将段大小增加 X 个字节以为分配 A 腾出空间,并增加 X 个字节以分配 B,然后释放 A。您无法减少分配的内存,因为 B 仍处于分配状态。而且由于段在整个程序中共享,如果程序的多个部分直接使用它,您将无法知道特定部分是否仍在使用。如果程序的一部分(假设 malloc)完全控制了 brk/sbrk 的使用,那么在别处调用它们将破坏程序。

    相比之下,mmap 可以按任何顺序取消映射,并且程序的一部分分配不会与程序的其他部分发生冲突。

  2. brk/sbrk 不是 POSIX 标准的一部分,因此不可移植。

    相比之下,mmap 是标准的和便携的。

  3. mmap 也可以做一些事情,比如将文件映射到内存中,这是使用 brk/sbrk.

    做不到的

it would have probably remained unused by the system for some time

为何提出此声明

见 1.

Maybe the OS keeps list of freed block

没有“障碍”。有一个(虚拟)块称为数据段。 brk/sbrk 设置该块的大小。

But doesn't mmap allocate on heap

没有。 “堆”位于数据段的末尾,堆是使用 brk/sbrk 增长的。 mmap 不在使用 brk/sbrk.

分配的内存区域中分配

mmap 在地址 space.

的其他地方创建一个新段
  1. does malloc actually save the free blocks that were allocated with sbrk for later usage?

如果它是首先使用 brk/sbrk 分配的,并且如果 malloc 没有减小“堆”的大小(以防万一),那么 malloc 可以重复使用之前 freed 的空闲“插槽”。这将是一件有用的事情。

  1. "then calling them elsewhere will break the program." can you give an example
malloc(42);
sbrk(42);
malloc(42); // maybe kaboom, who knows?

总结:不要使用brk/sbrk来设置段大小。也许也没有什么理由使用 (anonymous) mmap。在 C.

中使用 malloc