Linux 进程的虚拟地址范围

Linux 进程的虚拟地址范围,linux,memory,process,operating-system,linux-kernel,Linux,Memory,Process,Operating System,Linux Kernel,简而言之:进程的虚拟地址空间是连续的吗 我需要了解内核分配给进程的虚拟地址。如果我错了,请纠正我 在进程创建时,内核将虚拟内存分配给进程,并将进程不同段的虚拟地址的开始和结束存储在task\u结构的mm\u结构中 现在假设a进程已用完堆,需要增加堆大小。callsbrk() 如果虚拟地址范围是连续的,那么新分配的堆块是否从最初为此进程分配的范围之外提供?或者它的分配方式是新块与原始块相邻。如果没有空间(因为内存映射段就在那里),该怎么办。它是如何跟踪的? 如果虚拟地址范围不连续,vm_struc

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

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

在进程创建时,内核将虚拟内存分配给进程,并将进程不同段的虚拟地址的开始和结束存储在
task\u结构的
mm\u结构中

现在假设a进程已用完堆,需要增加堆大小。calls
brk()

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


你能澄清我的观点吗?

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

如果您对内核方面的内容感到好奇,我推荐两种参考:

  • 阅读一本关于Linux内核的书,例如,特别是
  • 浏览内核代码。内存管理代码位于中;从或开始

如果您想在系统上四处探索,可以在
/proc/$pid/maps
中查看每个进程的内存映射。有关详细信息,请参阅。

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

启动进程时,内核为动态链接器和进程本身分配多个映射。之后,动态链接器通过
mmap()
分配更多映射,进程可以通过
mmap()
分配更多映射,并通过
brk()
扩展堆malloc()
brk()
用于小于阈值的分配,将
mmap()
用于大于或等于该阈值(约128K IIRC)的分配

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

谢谢。。 根据我的理解,在阅读了上述文献之后

虚拟地址空间在整个进程中不连续,甚至在给定的内存段中也不连续。虚拟地址范围的不同块在内核中使用
vm\u area\u struct
(虚拟内存区域)的AVL树进行管理。因此,可以轻松地向进程的
任务结构
添加和删除虚拟内存块。参考号:。但是虚拟内存区域本身是连续的

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


非常感谢

我认为dlmalloc衍生品仍然使用
brk()
在特定阈值下进行分配,尽管我承认我最近没有研究过这一点。OTOH,IIRC,OpenBSD对每个分配都使用
mmap()
/proc//maps
的内容可能是您首先应该查看的,请提供。