1

我对有关虚拟内存的一些主题感到困惑。所以,我将逐点列出它们并提出问题。在回答时,如果您还列出一些我可以消除疑问的来源,我会更喜欢。我将参考 linux elf 可执行文件进行讨论。

  1. 我听说在 32 位系统中每个进程都有 4gb 的地址空间。当我检查我的一个可执行可重定位文件的 objdump 时,我看到它的限制从 00000000 到 ffffffff。它还包含内核空间。这是文件的地址空间。这就是我们说的虚拟内存吗?如果是,那么我已经读过虚拟内存机制允许运行非常大的进程,并且进程大小不受主内存大小的限制(我们可以在按需分页时将所需的页面带到主内存)。那么如果虚拟内存只有4gb,是不是限制程序的最大大小为4gb呢?此外,我检查了另一个文件的 objdump,它具有相同的地址(即 00000000 到 ffffffff)。那么这是什么意思?这是否意味着我们的文件是某种可重定位文件,将再次添加起始地址(尽管这看起来很荒谬,因为它已经是一个可执行的可重定位目标文件)。

  2. 我读过在已实现分段的内存中,cpu 产生虚拟(逻辑)地址。这个地址包含三个部分——段,段内的偏移量。此外,这里讨论的部分是代码、数据、堆栈等。

    在进程地址空间中,这些段从特定位置开始定位。那么,cpu的虚拟地址的内容是什么?生成的虚拟地址范围是否从 00000000 到 ffffffff?如果是,那么是在虚拟地址访问内容的过程,如下:-

    The segment part is looked up in the segment descriptor table to find the segment's
    starting address in linear address space. Then the offset is indexed within the segment and
    the resulting address is the linear address. Then, we look up the page table and map the
    address to physical address. If the page is not currently in the main memory, it is 
    brought. 
    

    这再次出现了这样一个事实,即任何时候都没有进程可以完全位于主内存中,因为这样整个内存将只被一个进程占用(因为进程的地址空间本身就是 4gb)。

    此外,如果所有进程的地址空间从 00000000 到 ffffffff,并且主内存中一次可以存在多个进程,那么所有进程都应该有自己的段描述符表,该表返回线性地址空间中的段地址

  3. 我读到操作系统在启动时被加载到主内存中。那么该操作系统与特定进程的内核空间中的内核代码有什么区别?此外,是否所有进程在其内核空间中都有自己的内核代码副本?
4

1 回答 1

2

这是一个非常开放的问题,有许多不同术语的混淆用法。我会尽可能多地解决您的问题,并提供一些其他有用的信息可能会有所帮助。

  1. “我听说在 32 位系统中每个进程都有 4GB 的地址空间。” 不完全正确。在 32 位系统中,每个进程的最大可寻址空间为 3.2GB。这并不意味着该内存被分配过,而且它肯定不会在进程启动时立即分配。“这就是我们说的虚拟内存吗?” 不,虚拟内存与进程的可寻址空间没有直接关系。稍后再谈。

  2. 这个问题真的没有意义,原因我将在下面解释。不过值得注意的是,多个进程确实可以同时放入内存,因为这些进程不会自动分配其全部潜在可用内存。(如果文本编辑器一打开就分配 4GB 内存,那它就不是流行的文本编辑器了!)

  3. 我不是专家,但我非常怀疑每个程序在运行时都有自己的内核代码副本。仅安全和性能问题就使这成为一个非常不可能的解决方案。

所以现在,一些可能对您有所帮助的定义。

  • 物理内存(通常!)是您 PC 中的 RAM。它是运行任何程序时 CPU 直接使用的快速物理内存。当您指定物理内存地址时,您正在根据内存硬件本身指定内存中的确切位置。
  • 虚拟内存(通常!)存储在较慢的媒体上,例如硬盘驱动器(通常称为分页文件)。当您的计算机运行进程的内存不足时,它会将一些当前物理内存内容复制到页面文件中,通常是从空闲或后台应用程序中复制。这会在物理内存中腾出空间,以便活动进程可以运行。如果不再在物理内存中的程序需要处理数据,则必须将其数据从页面文件重新加载到物理内存中——这反过来可能需要另一个程序物理内存中调出以腾出空间。术语“虚拟”与“物理”内存用于强调这种内存并不真正存在,但它仍然可用于计算机。虚拟内存的使用在性能方面非常昂贵,但它可以支持更大的大小:确实,可以拥有任意大量的可用虚拟内存,但是性能损失阻止了这成为超出某些限制的实用解决方案。
  • 逻辑内存地址是由单个进程使用的地址,它允许进程寻址自己的内存,而不必关心进程在物理内存中的加载位置。您的00000000to fffffffrange 是进程可用的逻辑范围,这是进程内用于引用内存的地址。内核会将其转换为物理CPU 在实际执行代码时使用的地址,基于进程内存的物理偏移(和分段)。此物理位置可以位于可用内存空间中的任何位置,如果应用程序被调出和调入,则物理位置可能会在应用程序的生命周期内发生变化。然而,应用程序本身只需要引用它自己的逻辑地址空间。术语“逻辑”与“物理”地址用于强调地址不是真实地址,而是相对于相关内存子集的地址 - 即相对于进程自己的内存空间。

我不是这方面的专家,但我希望这有助于澄清你的一些问题。

于 2012-10-15T12:58:02.430 回答