linux内核是否连续分配内存,例如从malloc
?如果没有大的部分可用,但较小的部分可以作为一个整体,Linux 会使用它吗?
3 回答
我假设在问题中,“连续”是指物理内存。
您在进程执行时看到的所有地址,例如当您使用gdb
or时addr2line
,都是虚拟地址。到物理内存的映射保留在底层。
malloc
通常不是系统调用。它是围绕特定平台的系统调用(例如mmap
or brk
)的包装器。当被进程调用时,它会导致调用进程的内存被扩展。
例如,malloc(40960)
可以请求 10 页内存,假设 4KB 页大小。内存管理单元(MMU) 不会立即在物理内存中分配 10 页。而是将新条目(本例中为 10 个)添加到调用进程的地址空间,即在该进程的页表中添加新条目。此虚拟内存将是连续的。
现在假设在稍后的执行过程中,进程尝试使用这块新分配的内存,此时,由于进程触及了未分配的内存,因此调用了页面错误。然后,MMU 将在 RAM 中分配一个实际的物理页(4096 个连续字节),更新页表并恢复进程的执行。
所以我们唯一可以确定的是,40960 字节中的 4096 字节(一页)在物理内存 (RAM) 中是连续的,尽管整个 40960 字节(10 页)在虚拟内存中显示为连续的。这 10 个页面中的任何一个或所有页面都可以映射到分散在 RAM 中的页面。
虚拟内存隐藏了这一点,并为进程提供了一个干净、连续的空间。MMU 使用页表通过将虚拟内存映射到物理内存来提供后端支持。
在 linux 内核中,内存分配是使用 kmalloc 或 vmalloc 完成的。kmalloc 分配物理上连续的内存,而 vmalloc 分配物理上不连续的内存。kmalloc 和 vmalloc 都会为您提供连续的虚拟内存空间。这是使用页表完成的。
我相信使用 malloc() 分配内存的物理映射可以是不连续的,并且确实是操作系统的责任。它可能是连续的,也可能不是连续的。
想到一个名为 kmalloc() 的函数,如果可用,它将分配连续的“物理”内存。