malloc 不在堆中分配连续的虚拟内存?

malloc 不在堆中分配连续的虚拟内存?

我意识到内部malloc调用mmapNULL作为第一个参数传递给 ,mmap以便内核将为映射选择合适的虚拟地址,这意味着malloc不一定会在堆区域中创建映射(由 brk 指针指示)。如果这是真的,则意味着多次调用后虚拟内存中的每个块之间将存在很多间隙,malloc因为每次调用malloc都返回一个与前一个不连续的新虚拟地址

我的问题:

  1. 如果每个块之间都有间隙,那么brk还有存在的理由吗?因为 的定义brk是指向堆顶,如下图所示:

    在此输入图像描述

    假设第一个malloc在堆中得到一个块(上图中的第一个块),第二个malloc可能得到第二个块,其起始地址低于第一个块,那么它brk指向第一个块的末尾还是第二个块的末尾?下面是描述这个问题的图片:

    在此输入图像描述

  2. 因此,一旦我们释放一个特定的块,分配器通常需要将相邻的空闲块与其合并,以便这三个块可以组合成一个大的空闲块。但由于现在每个块在虚拟内存中不是连续的,我们无法合并释放这些块,那么这种动态内存分配不是非常低效吗?

答案1

  1. malloc使用时mmap,不关心程序中断。malloc它使用两组内存:堆(程序中断之前的区域),它直接管理自己(使用 GNU C 库中的 arenas),以及mmaped 分配,它们委托给mmap.程序中断跟踪第一组内存,而不是第二组。不要求第二个是连续的。

  2. 释放的块由各自的分配器合并。如果内存是由mallocwithout分配的mmap,则这是malloc的责任(或frees)。如果内存是使用 分配的mmap,则这是mmap的责任(或munmap)。对于mmaped 块,合并空闲块甚至可能没有任何意义——如果它们从地址空间中删除,则无能为力。 ed 块可能会发生合并mmap,但如果两个地址空间分配是连续的并且具有相同的权限,则它会发生在分配时。

相关内容