进程的虚拟地址范围

sup*_*pie 6 linux memory operating-system process linux-kernel

简而言之:一个进程的虚拟地址空间是连续的吗?

我需要了解内核分配给进程的虚拟地址.如果我继续错误,请纠正我.

上的进程创建,内核分配的虚拟存储器至处理和存储开始,并在该过程的不同段的虚拟地址的结束mm_structtask_struct.

现在说一个进程已经用完了堆,需要增加堆size.calls brk().

如果虚拟地址范围是连续的,那么新分配的堆块是否从最初为此进程分配的范围之外提供?或者它是以新块与原始块相邻的方式分配的.如果没有空间(因为内存映射段正在那里),该怎么办?它是如何跟踪的?如果虚拟地址范围不连续,那么如何vm_struct跟踪堆(或任何其他段)的地址范围的不同块?

你可以清楚我的概念吗?

nin*_*alj 8

虚拟地址空间不连续.查看输出cat /proc/<pid>/mem.

在启动进程时,内核为动态链接器和进程本身分配几个映射.然后,动态链接器通过分配更多映射mmap(),并且进程可以通过分配更多映射mmap()并扩展堆通过brk().malloc()关于dlmalloc和衍生物brk()用于短于阈值mmap()的分配以及用于大于或等于该阈值的分配(大约128K IIRC).

在任何情况下,在调用时mmap(),内核通常将内存映射到远离堆的位置,因此通常有足够的空间来扩展堆.如果没有剩余的虚拟空间来扩展堆,brk()则会失败.


Gil*_*il' 6

不,进程的虚拟地址空间不一定是连续的.在过去,一个进程获得了内存brk,这确实迫使进程堆成为一个连续的内存区域.现在,内存分配完成mmap,可以逐页操作进程的虚拟内存.

如果你对内核方面感到好奇,我推荐两个引用:

如果您想在系统中进行浏览,可以查看每个进程的内存映射/proc/$pid/maps.请参阅如何在Linux下读取/ proc/$ pid/mem?欲获得更多信息.