进程的虚拟地址范围

时间:2011-05-08 15:22:18

标签: linux memory process operating-system linux-kernel

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

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

在创建流程时,内核将虚拟内存分配给流程,并在mm_struct的{​​{1}}中存储流程不同部分的虚拟地址的开头和结尾。

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

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

请你清楚我的概念吗?

3 个答案:

答案 0 :(得分:8)

虚拟地址空间不连续。请参阅cat /proc/<pid>/mem的输出。

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

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

答案 1 :(得分:6)

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

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

如果您想浏览系统,可以在/proc/$pid/maps中查看每个进程的内存映射。有关详细信息,请参阅How do I read from /proc/$pid/mem under Linux?

答案 2 :(得分:1)

感谢.. 按照我的理解,经过上述文献后,

虚拟地址空间在整个过程中不连续,甚至在整个给定的内存段中也不连续。并且使用vm_area_struct虚拟内存区域)的AVL树在内核中管理不同的虚拟地址范围块。从而轻松地将虚拟内存区域的块添加和删除到进程的task_struct。参考:Virtual Memory。但虚拟内存区域本身是连续的。

即。实际上task_struct包含一个指向mm_struct的指针,该指针包含一个指向AVL树头的指针(每个内存区域有一棵树)。树的节点只是vm_area_struct s,它有开始和结束指针来标记虚拟内存区域的开始和结束

非常感谢