虚拟内存与物理内存

3
假设我们在C语言中编写程序并打印其中一个变量的地址,那么在屏幕上打印出来的地址是变量的虚拟地址还是物理地址?如果是虚拟地址,为什么它仍然具有与物理内存位范围相同的范围?例如,在32位机器上,如果返回0x833CA23E。

1
C语言和C++编程语言都不包含任何关于“虚拟”或“物理”内存的概念,只有“内存”。在这两种语言中都无法回答这个问题。 - Kerrek SB
你只能在缺乏虚拟内存(和内存管理单元)的系统中找到物理地址和虚拟地址相同的机器,例如许多嵌入式系统。例如,ucLinux是Linux的一个版本,专门设计用于这些平台。FreeRTOS是一个微型操作系统(可以将其缩小到约8kB),不支持虚拟内存。 - Mike DeSimone
1
此外,在现代系统中,“位数”是指虚拟地址中的位数。物理地址可能没有那么多位(例如,在64位机器上,物理地址实际上只有40或48位被连接;高阶物理地址位被忽略)。在旧的架构中,它描述了内部数据寄存器的宽度,而(物理)地址具有更多的位数。例如,8086是16位的,但具有20位的寻址(1024k);6502是8位的,但具有16位的地址(64k)。 - Mike DeSimone
@MikeDeSimone:请注意,在硬件层面上,当前的x86-64虚拟地址也仅为48位。 - Oliver Charlesworth
是的,但指针仍然是8个字节,而不是6个字节。 - Mike DeSimone
3个回答

7
地址将成为虚拟内存中的虚拟地址,因为应用程序不知道物理内存。这是由内核和MMU隐藏的。 我不确定你所说的“相同位范围”的意思是什么。如果您有32位地址空间,则无论您拥有多少物理内存,它都将跨越整个32位空间。同样适用于64位。

这是否意味着如果我在一台32位机器上运行32位操作系统,拥有4GB的RAM,则虚拟内存空间和物理内存空间将是相同的? - shaveenk
1
@shaveenk,不是的,内核会选择一种映射方式,而内存管理单元会执行这种映射。通常情况下,你的程序要与内核和其他应用程序共享资源,因此将所有虚拟地址映射到所有应用程序的同一物理地址上是没有意义的。 - merlin2011
此外,如果您有虚拟内存支持,计算机可以将一些磁盘空间用作附加内存,当RAM页面未被使用且某些其他进程需要更多RAM时,将其“分页”到磁盘上。在进行分页时,涉及的进程会停止,因此它们不会注意到任何异常;对它们来说,看起来它们的数据始终在RAM中。 - Mike DeSimone

4
在大多数典型情况下(如Windows,Linux等),它将是一个虚拟地址。
在像Linux和Windows这样的典型情况下,虚拟地址和物理地址通常都是32位,因此在相同范围内具有数字变得不可避免。可以分配超过4GB的内存,如果这样做,您最终会得到大于32位的地址 - 但除非您采取特殊步骤进行操作,否则默认情况下将获得32位地址。
当您在32位操作系统下使用超过4 GB的内存时,通常会通过一些特殊的API进行操作,例如Windows的Address Windowing Extensions。使用这些API,您可以访问超过4 GB的RAM,但这不是代码的默认行为,即使接近可移植性。

一些操作系统(某些版本)还使用英特尔的物理地址扩展(PAE)来使整个系统能够访问超过4 GB的RAM,但即使在使用这些操作系统时,任何单个运行在系统上的进程仍然受限于寻址4 GB(即,使用PAE,您可以每个进程有一个4 GB的限制,而旧系统则总共只能寻址4 GB,需要在进程之间分配)。


0

在多数情况下,它将是一个32位的虚拟地址。

如果您的操作系统支持分页,那么它将是虚拟地址。可以使用分页将其映射到相同的物理地址。Linux和Windows都支持分页。

另一个重要因素是架构。在Intel x86 32位系统上,它将是32位地址。地址的前10位用于获取页面表。第二个10位用于从所选页面表获取页面。最后12位将给出该页面中的实际物理地址。

希望这回答了您的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接