为什么我们需要在操作系统中进行地址虚拟化?
Why do we need address virtualization in an operating system?
我目前正在学习操作系统课程,并且遇到了地址虚拟化。我将简要介绍一下我所知道的,然后再提出我的问题。
基本上,CPU(现代微处理器)生成虚拟地址,然后 MMU(内存管理单元)负责将这些虚拟地址转换为 RAM 中相应的物理地址。教授给出的例子是需要虚拟化,因为例如:你编译一个 C 程序。你运行吧。然后你编译另一个 C 程序。您尝试 运行 它,但内存中的常驻 运行ning 程序会阻止加载更新的程序,即使 space 可用也是如此。
根据我的理解,我认为没有虚拟化,如果编译器生成两个相同的物理地址,第二个不会 运行 因为它认为没有足够的 space为了它。当我们将其虚拟化时,因为在 CPU 中仅生成虚拟地址,MMU 将处理此 "collision" 并在 RAM 中为其他程序找到一个位置。(我们的教授给出了 MMU 的示例映射 table,它采用虚拟地址并将其映射到物理地址)。我认为这个想法与解决散列中的冲突非常相似 table.
能否就我的理解发表一些意见,如有任何进一步的说明,我们将不胜感激。
Could I please get some input on my understanding and any further clarification is appreciated.
你的理解大致正确。
澄清:
数据结构完全不像散列table。
如果有的话,数据结构更接近 BTree,但即使两者也存在重要差异。确实最接近一个稀疏分配的(Java)N维数组
它是映射页面而不是完整的虚拟/物理地址。 (一个完整的地址是页地址+页内偏移)。
没有碰撞问题。在任何时间点,所有用户/进程的虚拟 -> 物理映射都会提供从(进程 ID + 虚拟页面)到物理 RAM 页面或磁盘页面(或两者)的一对一映射。
我们使用虚拟内存的原因是:
进程隔离;即一个进程不能看到或干扰另一个进程内存
简化应用程序编写;即每个进程都认为它有一个连续的内存地址,并且每次都相同。 (第一次近似...)
简化编译、链接、加载;即编译器等不需要在编译时 "relocate" 编码或 运行 时考虑其他。
允许系统容纳比物理 RAM 更多的进程...尽管这会带来潜在的风险和性能损失。
我认为您对操作系统中与内存有关的事情存在根本性的误解。
(1) 你描述的是逻辑内存,不是虚拟内存。虚拟内存是指使用磁盘存储来模拟内存。未映射的逻辑内存页被映射到磁盘 space。
遗憾的是,术语逻辑内存和虚拟内存被混为一谈,但它们是不同的概念,区别变得越来越重要。
(2) 在一个进程中编程 运行。一个进程一次只能 运行 一个程序(在 unix 中每个进程通常只有 运行 一个程序(如果算上克隆调用者则为两个)。
在现代系统中,每个进程进程都有一个逻辑地址space(顺序地址),可以映射到物理位置或根本没有位置。通常,该逻辑地址的一部分 space 映射到所有进程共享的内核区域。逻辑地址 space 是用进程创建的。无地址space—无进程
在 32 位系统中,地址 0-7FFFFFFF 可能是(通常)映射到唯一物理位置的用户地址,而 80000000-FFFFFFFF 可能映射到系统地址 space所有进程。
(3) 逻辑内存管理主要作为一种安全手段;不是作为程序加载的一种方式(尽管它在这方面确实有帮助)。
(4) 这个例子对我来说毫无意义:
You compile a C program. You run it. And then you compile another C program. You try to run it but the resident running program in memory prevents loading a newer program even when space is available.
您忽略了进程的概念。一个进程一次只能有一个程序运行ning。在允许串行 运行ning 具有相同进程的程序(例如 VMS)的系统中,正在执行的程序会阻止加载另一个程序(或者加载另一个程序会导致 运行ning 程序终止) .这不是内存问题。
(5) 这根本不正确:
From my understanding, I think having no virtualization, if the compiler generates two physical addresses that are the same, the second won't run because it thinks there isn't enough space for it. When we virtualize this, as in the CPU generates only virtual addresses, the MMU will deal with this "collision" and find a spot for the other program in RAM.
MMU 不处理冲突。操作系统设置 tables 来定义进程启动时的逻辑地址 space。逻辑内存与散列无关 tables.
程序访问逻辑内存时的大致顺序是:
- 将地址分解为页面和页面内的偏移量。
- 该页面在table页面中是否有相应的条目?如果不是故障。
- 页面table中的条目是否有效?如果不是故障。
- 页面 table 条目是否允许在当前操作模式 (kernel/user/...) 中请求的访问类型 (read/write/execute)?如果不是故障。
- 条目是否映射到物理页面?如果不是 PAGE FAULT(从磁盘加载页面——虚拟内存——然后重试)。
- 访问页面table引用的物理内存。
我目前正在学习操作系统课程,并且遇到了地址虚拟化。我将简要介绍一下我所知道的,然后再提出我的问题。
基本上,CPU(现代微处理器)生成虚拟地址,然后 MMU(内存管理单元)负责将这些虚拟地址转换为 RAM 中相应的物理地址。教授给出的例子是需要虚拟化,因为例如:你编译一个 C 程序。你运行吧。然后你编译另一个 C 程序。您尝试 运行 它,但内存中的常驻 运行ning 程序会阻止加载更新的程序,即使 space 可用也是如此。
根据我的理解,我认为没有虚拟化,如果编译器生成两个相同的物理地址,第二个不会 运行 因为它认为没有足够的 space为了它。当我们将其虚拟化时,因为在 CPU 中仅生成虚拟地址,MMU 将处理此 "collision" 并在 RAM 中为其他程序找到一个位置。(我们的教授给出了 MMU 的示例映射 table,它采用虚拟地址并将其映射到物理地址)。我认为这个想法与解决散列中的冲突非常相似 table.
能否就我的理解发表一些意见,如有任何进一步的说明,我们将不胜感激。
Could I please get some input on my understanding and any further clarification is appreciated.
你的理解大致正确。
澄清:
数据结构完全不像散列table。
如果有的话,数据结构更接近 BTree,但即使两者也存在重要差异。确实最接近一个稀疏分配的(Java)N维数组
它是映射页面而不是完整的虚拟/物理地址。 (一个完整的地址是页地址+页内偏移)。
没有碰撞问题。在任何时间点,所有用户/进程的虚拟 -> 物理映射都会提供从(进程 ID + 虚拟页面)到物理 RAM 页面或磁盘页面(或两者)的一对一映射。
我们使用虚拟内存的原因是:
进程隔离;即一个进程不能看到或干扰另一个进程内存
简化应用程序编写;即每个进程都认为它有一个连续的内存地址,并且每次都相同。 (第一次近似...)
简化编译、链接、加载;即编译器等不需要在编译时 "relocate" 编码或 运行 时考虑其他。
允许系统容纳比物理 RAM 更多的进程...尽管这会带来潜在的风险和性能损失。
我认为您对操作系统中与内存有关的事情存在根本性的误解。
(1) 你描述的是逻辑内存,不是虚拟内存。虚拟内存是指使用磁盘存储来模拟内存。未映射的逻辑内存页被映射到磁盘 space。
遗憾的是,术语逻辑内存和虚拟内存被混为一谈,但它们是不同的概念,区别变得越来越重要。
(2) 在一个进程中编程 运行。一个进程一次只能 运行 一个程序(在 unix 中每个进程通常只有 运行 一个程序(如果算上克隆调用者则为两个)。
在现代系统中,每个进程进程都有一个逻辑地址space(顺序地址),可以映射到物理位置或根本没有位置。通常,该逻辑地址的一部分 space 映射到所有进程共享的内核区域。逻辑地址 space 是用进程创建的。无地址space—无进程
在 32 位系统中,地址 0-7FFFFFFF 可能是(通常)映射到唯一物理位置的用户地址,而 80000000-FFFFFFFF 可能映射到系统地址 space所有进程。
(3) 逻辑内存管理主要作为一种安全手段;不是作为程序加载的一种方式(尽管它在这方面确实有帮助)。
(4) 这个例子对我来说毫无意义:
You compile a C program. You run it. And then you compile another C program. You try to run it but the resident running program in memory prevents loading a newer program even when space is available.
您忽略了进程的概念。一个进程一次只能有一个程序运行ning。在允许串行 运行ning 具有相同进程的程序(例如 VMS)的系统中,正在执行的程序会阻止加载另一个程序(或者加载另一个程序会导致 运行ning 程序终止) .这不是内存问题。
(5) 这根本不正确:
From my understanding, I think having no virtualization, if the compiler generates two physical addresses that are the same, the second won't run because it thinks there isn't enough space for it. When we virtualize this, as in the CPU generates only virtual addresses, the MMU will deal with this "collision" and find a spot for the other program in RAM.
MMU 不处理冲突。操作系统设置 tables 来定义进程启动时的逻辑地址 space。逻辑内存与散列无关 tables.
程序访问逻辑内存时的大致顺序是:
- 将地址分解为页面和页面内的偏移量。
- 该页面在table页面中是否有相应的条目?如果不是故障。
- 页面table中的条目是否有效?如果不是故障。
- 页面 table 条目是否允许在当前操作模式 (kernel/user/...) 中请求的访问类型 (read/write/execute)?如果不是故障。
- 条目是否映射到物理页面?如果不是 PAGE FAULT(从磁盘加载页面——虚拟内存——然后重试)。
- 访问页面table引用的物理内存。