【问题标题】:Why do we need address virtualization in an operating system?为什么我们需要在操作系统中解决虚拟化问题?
【发布时间】:2015-10-26 02:35:36
【问题描述】:

我目前正在学习操作系统课程,并且遇到了地址虚拟化。我将简要介绍一下我所知道的,然后提出我的问题。

基本上,CPU(现代微处理器)生成虚拟地址,然后 MMU(内存管理单元)负责将这些虚拟地址转换为它们在 RAM 中的相应物理地址。教授给出的示例是需要虚拟化,因为例如:您编译了一个 C 程序。你运行它。然后你编译另一个 C 程序。您尝试运行它,但内存中的常驻运行程序阻止加载较新的程序,即使空间可用。

根据我的理解,我认为没有虚拟化,如果编译器生成两个相同的物理地址,第二个将不会运行,因为它认为没有足够的空间。当我们对它进行虚拟化时,因为 CPU 只生成虚拟地址,MMU 将处理这种“冲突”并在 RAM 中为其他程序找到一个位置。(我们的教授给出了 MMU 是一个映射表的例子,这需要一个虚拟地址并将其映射到一个物理地址)。我认为这个想法与解决哈希表中的冲突非常相似。

能否请我就我的理解提供一些意见,并感谢任何进一步的澄清。

【问题讨论】:

  • 进程隔离,简单明了。一个进程对另一个进程的意外影响可能为零,例如加载地址冲突、内存损坏等。

标签: c operating-system virtual-address-space


【解决方案1】:

能否请我就我的理解提供一些意见,并感谢任何进一步的澄清。

您的理解大致正确。

说明:

  • 数据结构与哈希表完全不同。

  • 如果有的话,数据结构更接近于 BTree,但即使与 BTree 也存在重要差异。它确实最接近已被稀疏分配的(Java)N 维数组。

  • 它是映射页面而不是完整的虚拟/物理地址。 (完整的地址是页地址+页内的偏移量。)。

  • 没有碰撞问题。在任何时间点,所有用户/进程的虚拟 -> 物理映射都会提供从(进程 ID + 虚拟页面)到物理 RAM 页面或磁盘页面(或两者)的一对一映射。


我们使用虚拟内存的原因是:

  • 进程隔离;即一个进程看不到或干扰另一个进程的内存

  • 简化应用程序编写;即每个进程都认为它有一个连续的内存地址设置,并且每次都设置相同。 (初步近似......)

  • 简化编译、链接、加载;即编译器等无需在编译时或运行时“重新定位”代码以考虑其他因素。

  • 允许系统容纳比物理 RAM 更多的进程...尽管这会带来潜在的风险和性能损失。

【讨论】:

  • 谢谢。所以一个进程认为它拥有自己的所有内存(没有限制)。然而,对于实际的潜在实际限制,MMU 会处理它。限制将是我认为 RAM 中的可用空间以及可以在某些辅助存储中完成的对该空间的扩展?
  • 是的,是的,是的。此外,还有一个问题是,如果许多进程都尝试同时使用大量内存,则可能会出现“抖动”。
【解决方案2】:

我认为您对操作系统中在内存方面发生的事情有一个基本的误解。

(1) 您描述的是逻辑内存,而不是虚拟内存。虚拟内存是指使用磁盘存储来模拟内存。未映射的逻辑内存页被映射到磁盘空间。

遗憾的是,逻辑内存和虚拟内存这两个术语混为一谈,但它们是不同的概念,区别变得越来越重要。

(2) 程序在进程中运行。一个进程一次只运行一个程序(在 unix 中,每个进程在其生命周期中通常只运行一个程序(如果算上克隆的调用者,则为两个)。

在现代系统中,每个进程进程都有一个逻辑地址空间(顺序地址),可以映射到物理位置或根本没有位置。通常,该逻辑地址空间的一部分映射到所有进程共享的内核区域。逻辑地址空间是随进程创建的。没有地址空间——没有进程。

在 32 位系统中,地址 0-7FFFFFFF 可能是(通常)映射到唯一物理位置的用户地址,而 80000000-FFFFFFFF 可能映射到所有进程都相同的系统地址空间。

(3) 逻辑内存管理主要作为一种安全手段;不是作为程序加载的一种手段(尽管它在这方面确实有帮助)。

(4) 这个例子对我来说毫无意义:

你编译了一个 C 程序。你运行它。然后你编译另一个 C 程序。您尝试运行它,但内存中的常驻运行程序阻止加载更新的程序,即使空间可用。

您忽略了过程的概念。一个进程一次只能运行一个程序。在允许以相同进程串行运行程序的系统(例如,VMS)中,正在执行的程序会阻止加载另一个程序(或加载另一个程序会导致正在运行的程序终止)。这不是内存问题。

(5) 这一点都不正确:

根据我的理解,我认为没有虚拟化,如果编译器生成两个相同的物理地址,第二个将不会运行,因为它认为没有足够的空间。当我们对其进行虚拟化时,由于 CPU 只生成虚拟地址,MMU 将处理这种“冲突”并在 RAM 中为其他程序找到一个位置。

MMU 不处理冲突。当进程启动时,操作系统设置定义逻辑地址空间的表。逻辑内存与哈希表无关。

当程序访问逻辑内存时,大致的顺序是:

  1. 将地址分解为页面和页面内的偏移量。
  2. 页表中是否有相应的条目?如果不是 FAULT。
  3. 页表中的条目是否有效?如果不是 FAULT。
  4. 页表条目是否允许当前操作模式(内核/用户/...)中请求的访问类型(读/写/执行)?如果不是 FAULT。
  5. 条目是否映射到物理页面?如果不是 PAGE FAULT(从磁盘加载页面——虚拟内存——然后重试)。
  6. 访问页表引用的物理内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-28
    • 2013-10-21
    • 1970-01-01
    • 2016-10-03
    • 2011-03-01
    • 2012-02-06
    • 1970-01-01
    • 2021-10-03
    相关资源
    最近更新 更多