在malloc期间内核中会发生什么?

liv*_*hak 46 c linux heap system process

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

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

nos*_*nos 67

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

简短的版本是mallocglibc 中的实现要么从brk()/ sbrk()system调用还是通过匿名内存获取内存mmap().这为glibc提供了一个很大的连续(关于虚拟内存地址)内存块,malloc实现进一步切片并在较小的块中切块并分发给您的应用程序.

是一个小malloc实现,它会给你一个想法,以及许多很多链接.

请注意,还没有关心物理内存 - 当内核虚拟内存系统通过brk()/ sbrk()或更改过程数据段mmap()时以及内存被引用时(通过读取或写入内存)来处理.

总结一下:

  1. malloc() 将搜索其管理的内存块,以查看是否有一块未使用的内存满足分配要求.
  2. 如果做不到这一点,malloc()将尝试扩展过程数据段(通过sbrk()/ brk()或在某些情况下mmap()).sbrk()最终在内核中.
  3. 内核中的brk()/ sbrk()调用调整struct mm_struct了进程中的一些偏移量,因此进程数据段将更大.首先,没有物理内存映射到扩展数据段所给的附加虚拟地址.
  4. 当首次触摸未映射的内存时(可能是实现的读/写malloc),故障处理程序将启动并陷入内核,内核将物理内存分配给未映射的内存.

  • 你能详细说明第4点是如何发生的吗?我想知道的是最终如何分配物理内存,以及内核代码的哪一部分可以做到这一点?谢谢. (3认同)

jwe*_*ich 11

你的答案中有一个错误 - malloc 直接处理物理内存.它处理分页虚拟内存 - 虽然我不确定它是否适用于每个架构.

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