虚拟内存实际上是如何增加内存空间的?

虚拟内存实际上是如何增加内存空间的?

我了解虚拟内存通过显示比实际可用更多的内存来欺骗程序。

但最终它必须将逻辑地址映射到实际的物理地址。那么它如何增加内存呢?

答案1

并没有增加身体的内存。它的目的则完全不同。它能做的是提供其他后备存储,让程序能够使用比物理可用内存更多的内存。

虚拟内存用于将进程彼此分离和隔离,还允许将内存访问转移到其他位置。

虚拟内存允许系统为每个进程提供与其他进程隔离的内存空间。程序可以在自己的空间中有效运行,这使它们可以完全访问整个地址空间,而不必绕过可能也需要使用“相同”地址的其他程序。这具有增加可靠性和安全性的副作用,因为进程不能轻易相互干扰。

应用程序的虚拟内存空间是根据需要构建的。应用程序看起来(对它自己而言)位于一个连续的内存块中,但实际上可能完全分散在物理内存中。

虚拟内存还允许捕获和转移内存访问,这使我们能够使用交换文件等功能。这意味着我们可以将最近未使用的内存部分推送到磁盘,并设置一个指针,表示“此内存块位于文件 x 中的位置 y”,然后我们可以释放物理内存区域供其他应用程序使用。当应用程序需要该内存时,可以从磁盘读回,将其放置在物理 RAM 的某个位置(可能与之前的位置不同),然后映射回与之前相同的虚拟内存位置。

与页面文件的使用方式相同,虚拟内存也可以允许操作系统对程序的共享库进行有效的“延迟”加载。当主程序告诉操作系统它想要使用某个库时,操作系统可以通过检查库的要求来节省时间,为应用程序分配虚拟内存区域的空间,而不是加载整个库,而是可以推迟从磁盘加载库的页面,直到真正需要它们为止。通过这种方式,库中唯一被加载到 RAM 中的部分是程序实际使用的部分,从未使用的部分永远不会被加载,因此不会浪费 RAM。

使用这些技术,我们可以提高系统的稳定性,并允许更多进程在有限的空间内运行,而不会过度影响彼此。它不会“增加内存”,而是让我们更有效地利用现有资源。

交换文件由虚拟内存系统启用,但过去被混淆为存在虚拟内存。

答案2

外行人的解释

当使用该内存时,系统必须将每个虚拟地址映射到物理地址,但是并非所有内存都同时使用。例如,假设您的浏览器中有 20 个选项卡,每个选项卡占用 1GB 内存。在没有虚拟内存支持的操作系统中,您需要 20GB 的 RAM 才能实现此功能。诀窍在于,您不会同时浏览所有 20 个选项卡,因此具有虚拟内存的操作系统将使您能够仅使用几 GB 的 RAM 来使用浏览器,将不活动的选项卡交换到磁盘。

更复杂的方面

虚拟内存并非专门用于交换。它的主要目的实际上是避免 RAM 碎片化,这在没有虚拟内存管理的系统上是一个大问题:您可能有 1GB 的可用 RAM,但如果它是 10MB 的块,那么请求 100MB 的应用程序将无法运行。

随着时间的推移,虚拟内存有了更多的用途,特别是随机文件访问:如果强制按顺序读取文件,许多应用程序(如数据库)将变得非常慢,而如果操作系统允许它们假装整个文件位于(虚拟)内存中并根据访问模式优化磁盘 IO 和缓存,它们的运行速度就会快得多。

答案3

虚拟内存不会增加内存,实际上不会增加​​更多主内存硬件。但它可以增加可用地址的范围。因此,一个正在运行的程序可能由一个代码段和一个数据段(堆栈和堆)组成,这两个段都可以占用虚拟的地址大于范围身体的机器的物理存储空间提供的地址。诀窍在于,在任何时候,只有一小部分虚拟地址由物理主内存支持[但一切最终都由磁盘存储支持]. 这是因为参照位置:任何时刻,只有程序段中一个或多个连续的小段中的指令被执行,只有数据段中一个或多个连续的小段中的数据被操作[当然,其行为实际上更加复杂,但它在大部分时间内确实遵循这种模式]

答案4

虚拟内存增加了程序可以处理的数据量。从软件的角度来看,我们(通常)不关心数据存储在哪里。它可以存储在物理 DRAM 内存中,可以存储在插入机器的闪存驱动器上,甚至可以存储在旋转盘上。软件关心的是,当它请求访问该数据时,它会成功。

在实际操作中,我们也希望程序运行得更快。速度考虑到这一点,我们确实关心数据在哪里。我们希望最常访问的数据存储在允许最快访问的硬件中。我们的程序将喜欢完全耗尽 DRAM。但是,我们通常没有足够的 DRAM 来实现这一点。虚拟内存是一种解决方案。

有了虚拟内存,操作系统就可以将一段时间内未使用的数据“分页”出来,并将其存储在硬盘上。这仍然可以访问,只是速度较慢。如果程序请求硬盘上的数据,操作系统必须花时间从磁盘读取数据,并将其移回 DRAM。

理论上,它可以直接从磁盘读取数据。但是,这样做是有原因的。程序不希望意识到所有这些复杂性。我们可以编写软件,智能地将数据放在磁盘上(这称为缓存)。但是,这需要大量额外的工作。我们在代码中可以做到的最快方法是:

if data is not in memory
    read data from disk into memory
operate on data

精明的读者会注意到,即使数据在内存中,我们也必须有一个条件来检查它是否存在。这比直接在内存中操作要慢得多!

虚拟内存通过在 CPU 上执行硬件检查来解决此问题。CPU 能够非常快速地执行此虚拟内存操作,因为它可以为此分配硬件。任何仅通过软件执行此操作的尝试都必须使用 CPU 的通用部件,而这些部件自然比专用晶体管慢。

这就是为什么我们总是将数据分页回内存,而不是从磁盘读取数据并就此搁置。我们将内存分成“页面”,每个页面都标记为内存中存在或不存在。操作系统以方便 CPU 直接使用的格式维护此表。每当程序访问存在的数据时,CPU 上的硬件都会让它们直接访问 DRAM 中的数据。当数据不存在时,会发出“页面错误”,告诉操作系统将该页面从磁盘加载到内存的某个物理页面,并更新表格以将 CPU 指向这个新的物理页面。

整个问题的关键在于尽量减少其使用。在实践中,我们发现操作系统非常擅长选择将哪些数据保留在内存中以及将哪些数据分页到磁盘,因此绝大多数内存访问都不会导致页面错误。

相关内容