【问题标题】:what happens in the kernel during malloc?malloc 期间内核中发生了什么?
【发布时间】:2011-08-08 15:15:18
【问题描述】:

我在一次采访中被问到这个问题。他们想知道的是,当用户调用 malloc(4) 分配 4 字节内存时,操作系统(Linux)如何响应?哪个子系统响应这个系统调用?

我告诉他 malloc() 将由内存管理子系统提供服务。 malloc() 实现会遍历空闲内存(物理内存)的列表,我们称之为空闲列表,并找到一个大于或等于 4 Bytes 的合适的块。一旦找到这样的块,它将从空闲列表中删除并添加到已使用列表中。然后该物理内存将映射到进程堆 vma 结构。他似乎对这个答案不太满意。好友系统如何适应这个?任何帮助将不胜感激。

【问题讨论】:

  • 他当时很生气。 malloc() 在用户模式下实现。
  • @Chris:主要是。 malloc 最终可能会调用 sbrk。
  • @Chris:不一定。这里给出的答案意味着malloc() 从物理内存中分配是错误的。
  • 另外,“操作系统”与“内核”不同;我认为,在谈论 unix 时,将“操作系统”解释为“内核、引导加载程序、libc 和基本用户模式程序,如 init、getty、login 和朋友”是公平的。取决于面试官如何表达他的问题,谈论分配器在用户模式下的作用可能是一个公平的答案。
  • 猜他对你在用户调用 malloc 和内核函数 malloc 之间的混合不满意。你描述的应该是内核malloc的功能。

标签: c linux process heap-memory system


【解决方案1】:

当用户空间应用程序调用malloc() 时,该调用不会在内核中实现。相反,它是一个库调用(实现了 glibc 或类似的)。

简而言之,glibc 中的malloc 实现要么从brk()/sbrk() 系统调用获取内存,要么通过mmap() 获取匿名内存。这为 glibc 提供了一个大的连续(关于虚拟内存地址)内存块,malloc 实现进一步将其切成更小的块并分发给您的应用程序。

Here 是一个小的 malloc 实现,它可以为您提供想法,以及许多很多链接。

请注意,目前还没有任何东西关心物理内存——当进程数据段通过brk()/sbrk()mmap() 更改并且内存被引用时(由读取或写入内存)。

总结一下:

  1. malloc() 将搜索其托管的内存块,以查看是否有一块未使用的内存满足分配要求。
  2. 否则,malloc() 将尝试扩展进程数据段(通过sbrk()/brk() 或在某些情况下mmap())。 sbrk() 最终进入内核。
  3. 内核中的brk()/sbrk()调用调整了进程的struct mm_struct中的一些偏移量,所以进程数据段会更大。起初,不会有物理内存映射到扩展数据段所提供的附加虚拟地址。
  4. 当第一次接触到未映射的内存时(可能是 malloc 实现的读/写操作),故障处理程序将启动并捕获到内核,内核会将物理内存分配给未映射的内存。李>

【讨论】:

  • 您能否详细说明第 4 点是如何发生的?我只想知道最终是如何分配物理内存的,内核代码的哪一部分是这样做的?谢谢。
  • @ArjunBora 不,这是一个相当大的话题。请提出一个单独的问题。
【解决方案2】:

malloc 直接处理物理内存。它处理paged virtual memory - 虽然我不确定它是否适用于所有架构。

当您的程序尝试分配内存并且空闲列表不包含大小等于或大于请求大小的块时,将分配一个完整的新页面。页面大小取决于体系结构(x86 上为 4096 字节)。页面分配只有内核才能执行,因此malloc 调用可能会导致系统调用。然后将新地址添加到空闲列表中,malloc 根据其实现操作空闲列表(例如检查 glibc)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-02
    • 1970-01-01
    相关资源
    最近更新 更多