什么是虚拟内存?

Yac*_*oby 32 virtual-memory

我仔细检查了我的“虚拟记忆”笔记,课本中的定义是:

分配一部分辅助存储作为主存储器的一部分的过程

正如维基百科所说:

虚拟内存是一种计算机系统技术,它给应用程序的印象是它具有连续的工作内存(地址空间)

和(维基百科也说)

请注意,“虚拟内存”不仅仅是“使用磁盘空间来扩展物理内存大小”

任何人都可以澄清哪个是正确的?

Cap*_*ult 45

Note that "virtual memory" is more than just "using disk space to extend physical memory size"
Run Code Online (Sandbox Code Playgroud)

虚拟内存是提供给每个进程的抽象层。比方说,计算机有 2GB 的物理 RAM,地址从 0 到 2G。一个进程可能会看到 4GB 的地址空间,它完全属于它自己。从虚拟地址到物理地址的映射由内存管理单元处理,该单元由操作系统管理。通常这是在 4KB“页面”中完成的。

这提供了几个功能:

  1. 一个进程不能看到其他进程中的内存(除非操作系统想要它!)
  2. 给定虚拟地址的内存可能不在同一物理地址
  3. 虚拟地址处的内存可以“调出”到磁盘,然后在再次访问时“调入”。

您的教科书将虚拟内存(错误地)定义为 #3。

即使没有任何交换,如果您为执行 DMA(直接内存访问)的设备编写设备驱动程序,您也特别需要注意虚拟内存。您的驱动程序代码在 CPU 上运行,这意味着它的内存访问是通过 MMU(虚拟)进行的。该设备可能根本经过MMU,所以它看到原始物理地址。因此,作为驱动程序编写者,您需要确保:

  1. 您传递给硬件的任何原始内存地址都是物理的,而不是虚拟的。
  2. 您发送的任何大(多页)内存块在物理上都是连续的。一个 8K 阵列可能实际上是连续的(通过 MMU)但是两个物理上分开的页面。如果您告诉设备将 8K 的数据写入对应于该数组开头的物理地址,它将在您期望的位置写入第一个 4K,但第二个 4K 会在某处损坏某些内存。:-(


Lee*_*e B 7

我会试着慢慢开始,然后为你把这一切放在一起。就像这样:

常用的虚拟内存是指“分页”。顾名思义,分页就像人类的记事本。

当您计算简单的总和或学习简单的信息时,您可以在头脑中完成所有操作:您只需加载所有信息,对其进行处理,然后得到答案。这就像一台计算机从硬盘驱动器加载文件——它将程序或图片或其他需要工作的信息加载到它的“真实内存”(或“物理内存”)中,并用它的“大脑”处理它们(它的处理器)。

但是,当您学习复杂的信息或处理复杂的总和时,您可能无法一次将所有这些都放在脑海中。您感到困惑,开始放慢速度,无法立即将所有内容保留在那里,并且必须忘记一些事情才能记住其他事情。

人类的解决方案是使用记事本。我们在页面上记下所有我们无法一次记住的东西,但在计算时参考它们。我们可能无法记住当月的大量销售数据列表,但我们可以查看页面,一次获取一点信息,并逐一处理。这就像计算机对其内存进行“分页”——将充满信息的页面写入页面,然后将其放入“虚拟内存”以供以后参考,并意识到它需要一个页面,然后将该页面从虚拟内存加载回实内存。在 linux 和 unix 上,这些页面存储的地方字面称为“页面文件”,内存中数据的页面字面称为“页面”。不同的系统对这些东西有不同的名称,但大体的概念大同小异。

所以真的,分页非常简单。信息的所有页面都无法放入内存中,因此有些页面会放在磁盘上,稍后再加载。

现在,更复杂的是,现代系统具有内存映射和内存保护功能,这些通常由计算机中的同一个硬件系统处理:内存管理单元或 MMU。

在(现代)多任务计算机中,可以同时运行多个程序并具有内存保护功能,每个程序通常与运行在同一系统上的其他程序分开。这样,一个程序不能简单地通过访问其内存来改变另一个程序——MMU 在物理上将一个程序的地址空间与其他程序的地址空间分开。换句话说,用户的程序看不到其他用户的程序,甚至其他程序。他们看不到“真实记忆”——他们看到的是自己的“虚拟记忆”。

现在,这个内存隔离概念和页面文件概念是两个概念上不同的东西,这可能是您感到困惑的原因。然而,关键是它们都使用 MMU——内存管理单元,它将内存分成页面,并将页面映射到虚拟地址空间。

所以,当一个程序请求某个“内存地址”的内存时,真正发生的是该程序的内存页和它们对应的地址(程序的“地址空间”)被查找,对应的页找到那个内存块。该页面可以加载到实际内存中的某个位置,在这种情况下,程序可以访问,或者可以将其分页到磁盘。如果它被调出,则会触发“页面错误”——磁盘被访问,页面被加载到内存中。因此该程序即使在没有足够内存的情况下也能工作,但它运行缓慢,如果它必须使用磁盘来进行通常非常快速的内存访问。

现在,如果没有足够的空间将该页面加载到内存中,那么您就有问题了。在这种情况下,内存中已经存在的一些 OTHER 页面必须“交换”到磁盘,因此可以加载第一个程序的页面。或者,它们可能同样是来自同一程序的页面。您有时会在图形程序中看到这种情况,例如,在负载较重的系统上,当图片的一部分加载缓慢并快速绘制时,下一部分加载同样缓慢并快速绘制,当您返回使用第一个时部分,它再次变慢。那是因为它们被加载以进行处理,然后再次换出,因此可以处理其他事情。显然,这是一种非常缓慢的工作方式,而您真正需要的是更多的 REAL 内存。