初识“虚拟内存”

初识“虚拟内存”
0

认识“内存”

首先要说明一下,本文所说的“内存”是指计算机科学中所指的内存,专业名称为“随机存取存储器”,英文 Random Access Memory,缩写 RAM。

我们可以把内存看作是中央处理器(CPU)可以直接访问的一块线性的存储空间。所谓“线性”,就是说内存可以看作是很多很多以连续的自然数(0、1、2、3、4……)为编号的格子组成的。这里说的一个格子通常就是一个字节(byte)的存储空间。而 0、1、2、3、4 这些编号就称为这一个个字节的“内存地址”。CPU 访问内存的时候,是通过内存地址(格子的编号)从内存中对应的格子中存取数据。

你在电脑或者手机上的所有程序,在执行的时候都必须先将要执行的程序指令加载到内存中。程序指令执行时需要用到的数据,通常也会放在内存中。

要准确认识内存,我们还要再说一下另一种存储器:硬盘。它们两者的区别,简单来说就是:

  1. 内存的访问速度比硬盘的访问速度快两个数量级,从内存读取 1 MB 数据比从硬盘读取 1 MB 数据快 100 倍甚至几百倍(这里说的是同一时代中普及使用的内存与硬盘的比较);
  2. 存储同样大小的数据的内存的制造成本比硬盘的制造成本大得多;
  3. 一般的内存是易失性存储器,即断电后就不能存储数据了,而硬盘断电之后还能存储数据。

由于以上原因,内存其实就可被看成是硬盘的一个缓存。由于内存断电后不能存储数据,所以数据必须存储在硬盘上;但如果 CPU 直接从硬盘读取数据的话,速度就太慢了,所以要先把数据从硬盘读取到内存中,CPU 则从内存中读取数据。CPU 写出数据也要先将数据写在内存中,再把数据从内存写到磁盘。

“虚拟内存”产生的背景

现在我们使用的电脑和手机上,都是有很多程序在同时运行的。如果所有程序在 CPU 中执行时都可以直接访问内存的话,那么一个程序就可以访问到另一个程序的数据,例如某个恶意程序可以读取到你在网页浏览器程序中输入的账号密码。这样显然是不行的。

为了解决这个问题,现代的 CPU 会向操作系统提供一套叫做“虚拟内存”的机制,让操作系统可以为各种应用程序的内存空间和实际的物理内存空间建立映射关系。例如把内存地址为 1000 到 1999 的物理内存映射为程序 A 的内存地址为 2000 到 2999 的虚拟内存,把内存地址为 2000 到 3999 的物理内存的空间映射为程序 B 的内存地址为 1000 到 2999 的虚拟内存。这样程序 A 和程序 B 可以访问各自的地址为 2500 的内存但不会相互影响。


如果一个程序访问的内存地址超出操作系统给它分配的虚拟内存,那么 CPU 将触发操作系统的内存越界处理程序,操作系统会调用程序的错误处理逻辑,或者终止该程序。

虚拟内存的其他用途

把程序的内存数据暂存在硬盘上

在物理内存空间不足的情况下,操作系统可以将某些不繁忙的程序的内存数据转移到硬盘上,然后在这些虚拟内存对应的映射上做个记录,从而使正在运行的应用程序可使用的总内存空间大于物理内存的空间。

例如操作系统可以把上面例子中分配给程序 A 的物理地址为 1000 到 1999 的内存数据转移到硬盘上,然后把这一段物理内存分配给程序 C 使用。在程序 A “看来”,它可用的内存没有变,它仍然可以访问地址为 2000 到 2999 的虚拟内存。在程序 A 访问到这段虚拟内存的数据时,CPU 会触发操作系统的处理程序,将硬盘上的内存数据恢复到物理内存中。操作系统有可能是先把属于程序 B 的地址为 3000 到 3999 的物理内存的数据存到硬盘中,再将程序 A 的内存数据恢复到该段物理内存中。而在操作系统将内存数据存到硬盘中,再恢复到内存中的整个过程,程序 A “看到”的虚拟内存的地址是没有改变的,仍然是 2000 到 2999。

写时复制

一些 CPU (例如电脑上常见的 Intel 和 AMD 的 CPU)提供的虚拟内存机制除了内存映射以外,还提供了对虚拟内存的访问控制的功能,让操作系统可以设置某块虚拟内存只能读不能写,或者只能当指令执行不能当数据存取。

Linux 的 fork 进程的命令就利用了这个功能。fork 命令会复制一个新的进程出来,新的进程的内存数据与原进程一模一样。但是 fork 命令并不会马上把原进程的内存数据复制一份,而是把新进程的虚拟内存都映射到原进程虚拟内存对应的物理内存上,但把该虚拟内存设为只能读不能写。等到新进程需要写内存时,触发操作系统的写保护处理程序,Linux 再将该物理内存的数据复制一份,让新进程的虚拟内存映射到复制数据的物理内存。这样新进程不写内存时就可以节省复制内存数据的开销。

总结

“虚拟内存”技术让操作系统可以自主设置每个应用程序进程的虚拟内存与物理内存的映射,达到进程间内存隔离的目的;还能通过将物理内存中的数据转移到硬盘上来使应用程序可用的总内存空间大于实际的物理内存空间。对虚拟内存的访问控制功能还能让操作系统实现“写时复制”的功能。

1赞

写得不错:+1:
建议继续多科普下计算机原理知识