【问题标题】:How does the system define the portion of virtual memory a process gets?系统如何定义进程获得的虚拟内存部分?
【发布时间】:2014-01-18 04:01:52
【问题描述】:

如果是 32 位系统(假设是 Windows),则虚拟地址空间为 4GB。所以CPU可以生成这个范围之间的任何地址。那么不应该一个进程也能够处理这个范围内的任何地方吗? 都说每个进程都有自己私有的虚拟地址空间,那么系统是如何促成这个的呢?

换句话说,CPU 生成一个 32 位地址,然后将其转换为物理地址。现在 CPU 怎么知道一个特定的进程必须只寻址虚拟地址空间的特定部分(它的私有虚拟地址空间)。

假设一个进程从其私有虚拟地址空间中寻址一个地址,会发生什么?

【问题讨论】:

    标签: windows memory memory-management virtual-memory


    【解决方案1】:

    程序必须在 Windows 上调用 VirtualAlloc() 来告诉操作系统它想要使用一块虚拟内存。由于从堆分配内存或加载 DLL,通常会间接调用。

    反过来,操作系统设置页面映射表,CPU 使用该表将程序中使用的虚拟地址转换为物理 RAM 地址,作为其地址总线引脚上的输出。每当 CPU 在虚拟内存地址读取或写入数据或执行代码时,可能会发生以下三种异常情况之一:

    • 如果页映射表中没有条目,则 CPU 会引发一般保护故障陷阱。操作系统验证地址无效并终止程序
    • 如果页面尚未映射到 RAM,则 CPU 会引发页面错误陷阱。操作系统会找到未使用的 RAM 页,并在必要时换出已使用的页。并确保内容有效,必要时从文件或页面文件加载。并更新表条目,使其现在具有 RAM 页的物理地址。执行恢复正常
    • CPU 验证是否允许访问该页面。对标记为只读的页面的写入或在标记为不执行的页面中执行指令会生成一般保护故障陷阱。操作系统终止程序。

    每个进程都有自己的一组页面映射表,确保一个进程无法访问另一个进程使用的 RAM 页面。除非特别请求共享,否则对于从可执行文件和内存映射文件加载的代码页来说很常见。上下文切换加载 CR2 寄存器,即包含页映射表地址的 CPU 寄存器。

    因此,没有任何情况下进程可以在其私有虚拟地址空间之外寻址内存,缺少匹配的分页表条目确保这会终止程序。

    【讨论】:

      【解决方案2】:

      整个 4 GB 地址空间可供进程使用(尽管通常上半部分为内核数据保留),MMU 将其中的一部分映射到物理内存。该进程不能“超出”其地址空间(允许使用所有 4 GB),但如果它的某些部分尚未映射到物理内存,则会引发硬件异常。

      地址空间被认为是私有的,因为操作系统会在任务切换时更改 MMU 的设置,因此每个进程都会看到不同的独立内存布局(尽管部分地址空间可以与其他进程共享)。

      【讨论】:

      • 任务切换时更改了哪些设置?
      • 对于我们现在讨论的最重要的是,虚拟 -> 物理内存映射和内存页面保护标志。
      猜你喜欢
      • 2011-08-19
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-13
      • 2012-09-23
      • 1970-01-01
      相关资源
      最近更新 更多