进程的虚拟地址范围
简而言之:进程的虚拟地址空间是连续的吗?
我需要了解有关内核分配给进程的虚拟地址的信息。如果我在继续过程中错了,请纠正我。
在进程创建时,内核为进程分配虚拟内存,并将进程不同段的虚拟地址的开始和结束存储在task_struct
的mm_struct
中。
现在假设一个进程已经耗尽了堆并且需要增加堆大小。调用brk()
。
如果虚拟地址范围是连续的,则新分配的堆块是否是从最初为此进程分配的范围之外提供的?或者是以新块与原始块相邻的方式分配的。如果没有空间怎么办(因为内存映射段就在那里)。它是如何被追踪的? 如果虚拟地址范围不连续,vm_struct
如何跟踪堆(或任何其他段)地址范围的不同块?
您能澄清我对此的概念吗?
In short: is the virtual address space of a process contiguous?
I need to know something about virtual address allocated to a process by the kernel. Please correct me if I am wrong as I proceed.
On process creation, the kernel allocated virtual memory to the process and stores the starts and ends of the virtual addresses of the different segments of the process in the mm_struct
in the task_struct
.
Now say the a process has run out of the heap and needs to increase the heap size.calls brk()
.
If the virtual address range is contiguous, is the newly allocated chunk of heap provided from outside the range that was allocated originally for this process? Or is it allocated in a way that the new chunk is adjacent to the original one. What if there is no space for that (because the memory mapped segment is lying there). how is it kept track of?
If the virtual address range is not contiguous, how does the vm_struct
keep track of the different chunks of the address ranges for the heap (or any other segment)?
Can you please clear my concept on that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不,进程的虚拟地址空间不一定是连续的。过去,进程通过 获取内存
brk
,这确实迫使进程堆成为一个连续的内存区域。现在内存分配是通过mmap 完成的
,它可以逐页操作进程的虚拟内存。如果您对内核方面的事情感到好奇,我推荐两个参考资料:
mm
目录;从mmap.c
或mm.h
< /a>.如果您想探索系统,可以在
/proc/$pid/maps
中查看每个进程的内存映射。请参阅 如何从 /proc/$ 读取Linux 下的 pid/mem? 了解更多信息。No, the virtual address space of a process is not necessarily contiguous. In the old days, a process obtained memory through
brk
, which indeed forced the process heap to be a contiguous zone of memory. Nowadays memory allocation is done throughmmap
, which can manipulate the process's virtual memory page by page.If you're curious about the kernel side of things, I recommend two references:
mm
directory; start withmmap.c
ormm.h
.If you'd like to explore around on your system, you can see each process's memory mapping in
/proc/$pid/maps
. See How do I read from /proc/$pid/mem under Linux? for more information.虚拟地址空间不是连续的。请参阅
cat /proc//mem
的输出。当启动一个进程时,内核为动态链接器和进程本身分配多个映射。之后,动态链接器通过
mmap()
分配更多映射,进程可以通过mmap()
分配更多映射,并通过brk()< 扩展堆/代码>。 dlmalloc 及其衍生产品上的
malloc()
使用brk()
来分配小于阈值的分配,使用mmap()
来分配大于或等于该阈值的分配阈值(大约 128K IIRC)。无论如何,当调用
mmap()
时,内核通常会映射远离堆的内存,因此通常有足够的空间来扩展堆。如果没有剩余虚拟空间来扩展堆,brk()
将失败。The virtual address space is not contiguous. See the output of
cat /proc/<pid>/mem
.When starting a process, the kernel allocates several mappings for the dynamic linker and for the process itself. Afterwards, the dynamic linker allocates more mappings via
mmap()
, and the process can allocate more mappings viammap()
and extend the heap viabrk()
.malloc()
on dlmalloc and derivatives usesbrk()
for allocations shorter than a threshold andmmap()
for allocations larger than or equal to that threshold (around 128K IIRC).In any case, when calling
mmap()
, the kernel usually maps memory far from the heap, so there is usually enough space to extend the heap. If there is no virtual space left to extend the heap,brk()
will fail.谢谢..
根据我的理解,在浏览完上述文献后,
虚拟地址空间在整个过程中并不连续,甚至在给定的内存段中也不连续。虚拟地址范围的不同块在内核中使用
vm_area_struct
(虚拟内存区域)的 AVL 树进行管理。从而轻松地向进程的task_struct 添加和删除虚拟内存区域块。参考:虚拟内存。但虚拟内存区域本身是连续的。即实际上
task_struct
包含一个指向mm_struct
的指针,该指针包含一个指向AVL树头的指针(每个内存区域一棵树)。树的节点只不过是vm_area_struct
,它具有开始和结束指针来标记虚拟内存区域的开始和结束,非常感谢
thanks..
after going through the said literatures as per my understanding,
the virtual address space is not contiguous throughout the process, as well as not even throughout a given memory segment. and the different chunks of virtual address ranges are managed in the kernel using an AVL tree of
vm_area_struct
(virtual memory areas). thereby easily adding and deleting chunks of virtual memory areas to thetask_struct
of the process. ref: Virtual Memory. but the virtual memory areas in itself are contiguous.i.e. in effect the
task_struct
contains a pointer tomm_struct
which contains a pointer to heads of AVL trees (one tree for every memory region). the nodes of the tree are nothing butvm_area_struct
s which has start and end pointers to mark the start and end of the virtual memory areasthanks a lot