我已经开始了解虚拟地址空间 (VAS),但我有几个问题:
最佳答案
虚拟地址与物理地址
在程序执行期间,变量(整数、数组、字符串等)存储在计算机主内存 ( RAM ) 中的某处。某些编程语言(如 C 或 C++)允许您获取存储给定变量的内存地址(使用 &
运算符),并操作该地址(添加、减去、打印等) .
这是一个打印变量内存地址的 C 程序:
#include <stdio.h>
int main(void) {
int variable = 1234;
void *address = &variable;
printf("Memory address of variable: %p\n", address);
return 0;
}
输出:Memory address of variable: 0x7ffc9e9662a4
现在,如果你在典型的台式计算机上编译并执行这个程序,使用典型的操作系统(如 GNU/Linux 或 Windows),这个程序打印的内存地址不是数据 1234
实际所在的硬件地址位于 memory chip 。这可能令人惊讶,但在程序使用的地址和硬件地址之间存在一定程度的间接性。64 位计算机上的虚拟地址空间
在 64 位计算机上,程序操作的内存地址是一个介于 0 和 18446744073709551615 之间的整数。这样的地址称为 虚拟 内存地址。这些地址的范围称为进程的 虚拟地址空间 。您可以要求操作系统 将 一系列虚拟内存地址映射到您计算机的物理内存,这样当您尝试在这些地址读取或写入字节时,您的程序不会因访问未映射的虚拟内存地址而崩溃.
通常,在 x86-64 计算机上,only 248 virtual memory addresses 可以成功映射到物理内存,因为 256 TiB 的可用虚拟地址空间被认为是足够的。将来,如果需要,处理器制造商可能会提高或取消此限制。
32 位计算机上的虚拟地址空间
在 32 位计算机上,有 232 个虚拟内存地址。在这些计算机上,程序操作的内存地址是一个介于 0 和 4294967295 之间的整数。
在 x86 32 位计算机上,通常对可以映射到物理内存地址的虚拟内存地址范围没有限制。
映射一系列虚拟内存地址
在 GNU/Linux 上,您可以通过调用函数
mmap()
来请求映射。在 Windows 上,您可以通过调用函数 VirtualAlloc()
来请求映射。这些函数将映射的大小作为参数,并返回现在由实际物理内存支持的第一个虚拟地址。如果物理内存已被其他进程完全使用,这些函数可能无法创建新映射。同样,如果您尝试访问(读取或写入)位于 mmap()
或 VirtualAlloc()
映射区域之外的虚拟内存地址的内容,操作系统将终止您的程序(通过发送段错误信号)。在 GNU/Linux 上,进程可以通过读取文件
/proc/self/maps
来检查在其虚拟地址空间中创建的映射。通过阅读命令 cat /proc/self/maps
的输出,您可以学到很多东西。硬盘驱动器
在典型的计算机上,主存是一个 semiconductor memory ,而 hard disk drive 只是一个辅助存储设备。
在典型的操作系统上,一系列虚拟内存地址只能映射到主内存(通常是半导体存储设备)。这样的范围不能直接映射到二级存储设备(通常是硬盘驱动器)而不使用主存作为中介。
关于linux - 虚拟地址空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65170779/