当进程启动时,它会获得自己的虚拟地址空间。虚拟地址空间的大小取决于您的操作系统。通常情况下,32位进程获得4 GiB(4吉比二进制)地址,64位进程获得18 EiB(18艾字节二进制)地址。
您无法以任何方式访问未映射到您的虚拟地址空间中的任何内容,因为根据定义,任何未映射到那里的内容都没有地址供您使用。您可以尝试访问当前未映射到任何内容的虚拟地址空间的区域,在这种情况下,您会收到一个段错误异常。
并非所有地址空间在任何给定时间都映射到某些内容。也不是所有内容都可能被映射(可以映射多少取决于处理器和操作系统)。在当前一代英特尔处理器上,最多可以映射256 TiB的地址空间。请注意,操作系统可以进一步限制其数量。例如,对于具有最多4 GiB地址的32位进程(默认情况下),Windows保留2 GiB用于系统和2 GiB用于应用程序(但有一种方法可以使其成为1 GiB用于系统和3 GiB用于应用程序)。
地址空间的使用情况和映射情况在应用程序运行时会发生变化。操作系统特定的工具将允许您监视正在运行的应用程序的当前分配内存和虚拟地址空间。
代码段、数据段、BSS等术语是指链接器创建的可执行文件的不同区域。通常情况下,代码与静态不可变数据是分开的,而静态分配但可变数据是分开的。堆栈与上述所有内容都是分开的。它们的大小由编译器和链接器计算。请注意,每个二进制文件都有自己的部分,因此任何动态链接库都将单独映射到地址空间中,每个库都有自己的部分映射到某个位置。然而,堆和栈不是二进制映像的一部分,通常每个进程只有一个堆栈和一个堆。
堆栈的大小(至少初始堆栈)通常是固定的。编译器和/或链接器通常有一些标志,您可以使用这些标志设置要在运行时使用的堆栈大小。堆栈通常“向后增长”,因为这是处理器堆栈指令的工作方式。使堆栈向一个方向增长,其他内容向另一个方向增长,可以更轻松地组织内存,在这种情况下,您希望两者都是无限制的,但不知道每个内容可以增长多少。
堆通常指进程启动时未预先分配的任何内容。在最低级别上,有几个逻辑操作与堆管理相关(并非所有操作系统都按照我在此处描述的方式实现)。
虽然地址空间是固定的,但某些操作系统会跟踪进程当前回收的哪些部分。即使情况不是这样,进程本身也需要跟踪它。因此,最低级别的操作是实际上决定要使用地址空间的某个区域。
第二个低级别操作是指示操作系统将该区域映射到某个内容。通常可以这样做。
可能还有我忘记的其他组合,但这些是主要的。
当然,实际使用的总空间取决于如何定义它。当前使用的RAM不同于当前映射的地址空间。但正如我上面所写的,操作系统相关工具应该让您找出当前正在发生的情况。