【问题标题】:How is memory allocated on heap without a system call?在没有系统调用的情况下如何在堆上分配内存?
【发布时间】:2012-02-26 14:05:17
【问题描述】:

我想知道堆上所需的空间是否不够大 这样就不需要 brk/sbrk 系统 all(移动数据段的中断指针(brk)),库函数(例如 malloc)如何在堆上分配空间。 我不是在询问堆管理的数据结构和算法。我只是问如果 malloc 不调用系统调用,它如何获取堆的第一个位置的地址。我之所以问这个问题是因为我听说并不总是需要调用系统调用 (brk/sbrk),因为它们只需要扩展空间。如果我错了,请纠正我。

【问题讨论】:

标签: linux operating-system memory-management


【解决方案1】:

简短的回答是它使用 sbrk() 来分配一个大块,此时它属于您的应用程序进程。然后,它可以进一步将其中的子部分作为单独的 malloc 调用进行打包,而无需向系统询问任何内容,直到它耗尽该空间并需要再次使用 sbrk()。

您说您不想要有关数据结构的详细信息,但只要说 malloc 的实现(即您自己的进程,而不是操作系统内核)正在跟踪它从该区域中的哪个空间就足够了该系统已被使用,并且仍然可以作为单独的 malloc 分发。这就像购买一大片土地,然后将其细分为单独的房屋。

【讨论】:

    【解决方案2】:

    基本思想是当你的程序启动时,堆很小,但不一定是零。如果您只分配 (malloc) 少量内存,则库能够在加载时在其拥有的少量空间内处理它。但是,当 malloc 用完该空间时,它需要进行系统调用以获取更多内存。

    该系统调用通常是 sbrk(),它将堆的内存区域的顶部向上移动一定量。通常,malloc 库例程将堆增加比当前分配所需的更大,希望将来的分配可以在不进行系统调用的情况下执行。

    malloc 的其他实现使用 mmap() 代替——这允许程序创建稀疏的虚拟内存映射。但是,基于 mmap() 的 malloc 实现与基于 sbrk() 的实现相同:每个系统调用保留的内存比当前调用所需的内存更多。

    查看此问题的一种方法是跟踪使用 malloc 的程序:您会看到对于对 malloc 的 N 次调用,您将看到 M 次系统调用(其中 M 远小于 N)。

    【讨论】:

    • @J Teller:感谢您的解释。实际上,我正在考虑库可以处理的堆空间很小的情况(正如您在第一段中提到的那样)。那么调用 malloc 会做什么呢?
    • 让我们想一个人为的简单说明性示例。假设 malloc 从它可以使用的内存区域开始,带有指向其基址的指针 (void *base_ptr) 和空闲的计数 (int free_bytes)。我们将其称为它的起始桶。然后,在调用malloc时,如果大小足够小到可以放入起始桶,则返回的指针将是base_ptr、base_ptr+=alloc_size和free_bytes-=alloc_size。这一直持续到 free_bytes 不够大来满足分配,然后它会执行 sbrk 或 mmap
    • 当然,我上一条评论跳过了所有有趣的数据结构、跟踪什么是免费的、碎片等。您可以查看维基百科文章以获得进一步阅读的良好介绍:en.wikipedia.org/wiki/C_dynamic_memory_allocation
    • Malloc 主要从加载二进制文件的代码中获取基指针(对于嵌入式系统,有时是链接描述文件)。基本上,启动程序和已启动程序之间有一个约定,全新的程序在加载时“只知道”堆的开始和结束位置。我会尝试在网上的某个地方找到更深入的解释...
    • dirac.org/linux/gdb/02a-Memory_Layout_And_The_Stack.php 的顶部附近有一个关于 linux 进程内存映射的快速介绍。基本上,exec 系统调用(shell 调用它来加载你的新程序)基于二进制设置内存的前几部分(文本、数据和 bss),你的新程序知道每个部分的开始和结束部分。然后在您的代码开始运行之前,libc 库开始运行一些设置,其中包括确定堆的开始位置,以及要分配的空间(如果有的话)。
    【解决方案3】:

    【讨论】:

    • 问题提到“没有系统调用”。
    猜你喜欢
    • 2019-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 2021-12-02
    • 2012-07-21
    相关资源
    最近更新 更多