从我的书中:
回顾了我们的第一次讨论,现代动态内存管理器不仅使用sbrk(),而且还使用mmap()。当释放大内存块但被位于它们之间的较小的、最近分配的块和分配的空间结束时,此过程有助于减少内存碎片的负面影响。在这种情况下,如果用sbrk()分配块,系统可能会使用它一段时间(或者至少大部分时间)。
有人能好心地解释使用mmap如何减少内存碎片的负面影响吗?给出的例子对我没有任何意义,而且一点也不清楚。
--它可能会被系统使用一段时间
为什么要这样说,当我们释放它时,系统可以稍后使用它。也许操作系统在堆中保留了已释放块的列表,以便在可能的情况下使用它们,而不是在堆中使用更多的空间。
请同时回答这两个问题。
发布于 2021-06-25 00:20:23
mmap()相对于sbrk()的
优势是什么?
brk/sbrk是LIFO。假设您将段大小增加X个字节数,以便为分配A腾出空间,而X个字节数用于分配B,然后释放A。您不能减少分配的内存,因为B仍然是分配的。而且,由于段是跨整个程序共享的,如果程序的多个部分直接使用它,您将无法知道特定部分是否仍在使用。如果程序的某一部分(比如malloc)完全控制了brk/sbrk的使用,那么在其他地方调用它们就会破坏程序。相反,mmap可以按任意顺序取消映射,并且程序的一个部分的分配不会与程序的其他部分冲突。
brk/sbrk不是POSIX标准的一部分,因此也不是可移植的。相比之下,mmap是标准的和可移植的。
mmap也可以将文件映射到内存中,而使用brk/sbrk.是不可能的。
--系统可能会在一段时间内没有使用它--为什么会提出这个声明?
见1。
可能操作系统保存了已释放块的列表
没有“积木”。有一个(虚拟的)块叫做数据段。brk/sbrk设置该块的大小。
但没有在堆上分配mmap
不是的。“堆”位于数据段的末尾,堆是使用brk/sbrk增长的。mmap不会在使用brk/sbrk分配的内存区域中分配。
mmap在地址空间的其他地方创建了一个新段。
如果首先使用brk/sbrk分配它,如果malloc没有减少“堆”的大小(如果可能的话),那么malloc可以重用以前是freed的空闲“时隙”。这将是一件有用的事情。
的例子吗?
malloc(42);
sbrk(42);
malloc(42); // maybe kaboom, who knows?总之:不要使用brk/sbrk来设置段大小。也许也没有理由使用(匿名) mmap。在C中使用malloc。
发布于 2021-06-25 00:18:38
当使用sbrk()时,堆只是一个大内存块。如果分配和释放的模式没有留下大的、连续的内存块,那么每一个大的分配都需要增加堆。这可能导致内存使用效率低下,因为堆中留下了所有未使用的空白。
使用mmap(),您可以拥有一堆独立的映射内存块。因此,您可以使用sbrk()堆来处理您的小分配(可以很好地打包),并可以使用mmap()进行大型分配。当您完成这些大块之一时,您只需删除整个映射即可。
https://stackoverflow.com/questions/68123943
复制相似问题