虚拟内存总是可用吗?

虚拟内存总是可用吗?

虚拟内存原理

虚拟内存的想法是创建一个与 RAM 中的实际地址不对应的虚拟地址空间。系统将内存的正式副本存储在磁盘上,并仅将最常用的数据缓存在 RAM 中。为了使其可行,我们将虚拟内存分成称为页面;典型的页面大小为 4 KB。我们还将 RAM 分为页框,每个大小与页面相同,准备容纳虚拟内存的任何页面。

我运行的是 Linux 系统,交换区域是空的,因为主内存中有足够的空间。话虽这么说,是否仍然存在带有页面的虚拟内存,并且进程是否会继续拥有虚拟地址而不是主内存中其段的物理地址?

如果磁盘中没有交换区怎么办,系统中是否也有虚拟内存?

简而言之,Linux系统中的虚拟内存总是可用吗?进程总是有虚拟地址吗?

答案1

虚拟内存(分页)在 CPU 级别启用。这意味着 CPU 使用 MMU 将虚拟地址(如应用程序所见)转换为物理地址。内存被分成页。页面可以加载到内存或加载到磁盘。如果页面位于磁盘上,则访问该页面会导致页面错误,该错误由操作系统处理(操作系统从磁盘加载页面)。

因此,如果没有交换,您仍然拥有虚拟内存,CPU 仍然使用 MMU 并将内存拆分为页面,但操作系统无法将这些页面移动到磁盘。

http://wiki.osdev.org/Paging

答案2

不。

正如 user996142 所提到的,有两种称为虚拟地址空间的东西。但是,您在问题中显示的定义更具体地讨论了交换空间。不管怎样,我认为这两种说法都相当令人费解。

在 CPU 级别,您需要有一个 MMU 来拥有所谓的虚拟内存地址。正如其他用户所提到的,计算机具有给定物理地址的物理内存。在大多数情况下,物理内存从 0 开始,逐渐增加到您拥有的内存总量。有些架构喜欢在末尾也有内存(地址-1、-2、-3...)。所有 CPU 都没有 MMU 芯片,特别是在嵌入式系统中。一些此类系统仍然使用 8 位 CPU,而实际上无法使用 MMU(无论如何,这些系统仅限于 64Kb 可寻址内存)。

在系统级别,虚拟内存就是您提到的交换区。同样,这不一定可用。在大多数 Linux 发行版中,交换区是在安装时自动创建的。然而,有些系统不会自动执行此操作(例如,DigitalOcean 提供的 Ubuntu 机器默认不提供交换空间...)在大多数情况下,拥有一些交换空间是一件好事,可以避免进程被操作系统恢复 RAM(因此,您不知道刚刚发生了什么)。

内核负责为您管理所有这些。

MMU部分是非常低级的。对于大多数实现,需要在 Linux 下运行进程。如果没有该功能,您要么需要可以在任何位置运行的进程(这在运行 68K 处理器的旧 Mac 上是一件有趣的事情,您将创建大约 64Kb 的代码块,可以放置在内存中的任何位置),或者拥有一种重新定位进程的方法...

笔记: 一段时间以来,Linux 内核已更新为每次重新启动时不再在同一 IP 地址运行进程。如果您尝试调试自己的进程并希望依赖这样的固定 IP 地址,这真的很烦人。但这更安全。但结果是,仅 MMU 不足以运行进程。每次重新启动时都必须重新定位它们,具体取决于内核当时选择的 IP。

交换是一个非常高的层,它允许您运行利用更多内存比将一些数据放在磁盘上的计算机上的数据要多。当然,速度方面会有巨大的损失。在大多数情况下,最好运行一个进程,一旦完成,就运行下一个进程,等等以避免交换到磁盘。

一个重要的方面是,进程的代码(汇编代码,对于 Python 和 php 等解释性语言,将是解释器二进制文件)不会更改,并且以只读模式在磁盘上可用。这意味着:您可以交换进程的部分代码,并在以后根据需要重新加载它,而无需交换 RAM 中的数据带来巨大的损失。数据必须写入磁盘,这很慢。只需要阅读代码即可。因此,如果进程代码的一部分从未执行过,则该代码页可以非常快速地换出并重新加载,以防稍后再次执行。该交换不需要交换磁盘或交换文件。因此,即使你的交换空间是 0Kb,内核仍然可以交换正在运行的进程的代码以节省一些 RAM。

答案3

如果 Linux 运行在带有内存管理单元 (MMU) 的 cpu 上,则虚拟内存始终处于使用状态。

“虚拟内存”一词在这里有两个相互交织的含义。它可以指进程内内存地址的虚拟分配,该内存地址可能对应也可能不对应于物理内存。它还可以指可通过将磁盘块映射到进程虚拟内存来将内存空间扩展到物理上可用的 RAM 之外的磁盘块。

Linux(以及一般的unix)是按需分页的,这意味着页面是按需从磁盘加载或从空闲内存池分配的。

进程中的页面可以处于来自多个来源的多种状态:

  • 可执行页面很可能与磁盘上的程序或共享库相关联。磁盘上有该页的副本,物理内存中也可能有该页的(只读)副本。这些页面可以由使用相关文件的所有进程共享(只读)。
  • 该进程的数据页可以位于物理RAM中。如果它在内存中,它可能是干净的或脏的。干净的数据页在交换区中有一个副本(如果需要可以释放)。脏页要么在交换中没有副本,要么该页已被修改(并且释放了交换页)。它也可能被换出,物理内存中没有副本。
  • 磁盘上的文件可以映射到进程的虚拟内存中。可执行页面被映射为只读(如上所述)。但也可以将可写文件映射为数据页,然后将其保存到文件而不是交换区。当映射的数据页被弄脏时,它很快就会机会性地写回文件。如上所述,映射页可以仅位于磁盘上,也可以在 RAM 中复制(干净或脏)。
  • 页也可以在虚拟内存中分配,但在物理 RAM 或磁盘上没有相应的数据。当进程请求更多内存但尚未(尚未?)使用它时,就会发生这种情况。从这样的页面读取将返回零。写入将导致物理页被清零,分配给进程,然后写入将完成。 (或者,如果不可能的话,该进程将因内存不足错误而被终止。)

因此,如果没有交换,仍然有虚拟(非物理)内存用于空的未初始化页面、可执行页面,并且还可以有映射数据页面。此外,物理内存包含在虚拟内存中,无论有或没有磁盘支持。

不同之处在于,如果没有交换,当系统内存不足时,只读页将被频繁刷新以加载其他页,并且除非与文件关联(无论是否已映射),否则脏页无处可去并被锁定物理内存。

这稍微简化了事情,因为还有磁盘文件的缓存页面,这些页面没有分配给任何进程的虚拟内存,但仍然涉及虚拟内存系统。此外,实现细节可能会以不同的方式对上述一些操作进行排序。

请注意,较旧的 UNIX 系统需要足够的交换空间来支持所有物理内存页,因此交换空间通常至少是 RAM 大小的两倍。 Linux 很早就放弃了这种策略,并且不需要任何交换。

相关内容