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