linux - 虚拟地址空间

标签 linux memory-management process virtual-memory virtual-address-space

我已经开始了解虚拟地址空间 (VAS),但我有几个问题:

  • 根据架构(32 位和 64 位)为每个进程创建多少 VAS?
  • 每个进程的VAS是在硬盘上创建的吗?如果是这样,如果没有足够的空间会发生什么?
  • VAS 和虚拟内存 (VM) 有什么区别?
  • 最佳答案

    虚拟地址与物理地址
    在程序执行期间,变量(整数、数组、字符串等)存储在计算机主内存 ( 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/

    相关文章:

    c# - 在 perl 和 c# 中使用套接字在本地计算机上进行进程间通信

    C# 进程 <实例>.StandardOutput InvalidOperationException "Cannot mix synchronous and asynchronous operation on process stream."

    linux - 在CENTOS6.8中使用shell移动文件夹但保留前面的结构

    php - *nix : Performing nested -exec with find command

    linux - lua 和 env lua 的区别?

    iphone - Objective-C 中的实例变量是否默认设置为 nil?

    ios - 将 NSMutableArray 的内容保存到文件

    linux - 为什么Qt中的MainWindow在启动程序后关闭?

    c++ - 将代码存储在头文件中会导致 C++ 中的内存管理问题吗?

    java - 对进程执行命令