Unix系统上进程启动时,进程虚拟地址空间大小是如何确定的?当流程数据段或堆栈必须增长时,VAS、PAS、通过 VMM 之间会发生什么?
看下图,VAS 似乎大于物理地址空间,我假设这允许分页到磁盘。
我问这个问题是因为在之前的问题中我已经回答过here,brk() 和 sbrk() 系统调用用于增加进程数据段的大小。然后堆栈的大小就会以某种方式增长。我的假设是该进程的 VAS 已经很大,并且 VMM 通过一些系统调用将页面映射到 VAS。
参考链接
Unix系统上进程启动时,进程虚拟地址空间大小是如何确定的?
简单的答案是,虚拟地址空间大小由指令集架构和操作系统决定。
在32位机器(支持虚拟内存)中,虚拟地址空间大小最大为2^32。
在64位机器中,虚拟地址空间大小最大为2^64。
在实践中,操作系统实现细节和硬限制意味着并非所有理论上可用的虚拟空间实际上都可用。
部分虚拟地址空间被保留给操作系统内核使用。 当在内核模式下运行时,操作系统需要能够寻址用户进程的所有页面。 例如,用户进程可以对其虚拟地址空间中任何位置的缓冲区发出
write
系统调用。 内核需要能够寻址缓冲区来复制数据。 同时,内核需要一个虚拟地址空间来存放自己的代码和数据结构以及缓冲区。 这是通过为操作系统保留部分虚拟地址空间来实现的。 例如,在当前一代 64 位 Linux 系统上,从 0x80000000 到 0xffffffff 的地址是为内核保留的。
理论上可以为进程提供完整的 32 位或 64 位虚拟地址空间,但会使操作系统更加复杂,并可能增加系统调用上下文切换开销。 Linux 不支持这个。
当流程数据段或堆栈必须增长时,VAS、PAS、通过 VMM 之间会发生什么?
简短的回答是,虚拟内存系统在页表中添加更多条目,以将更多虚拟地址空间映射到物理 RAM 页面。
(我假设您已经研究过虚拟内存页表的工作原理。如果没有,请阅读以下内容:https://en.wikipedia.org/wiki/Page_table)