-
五分钟扫盲:程序在计算机中是如何运行起来的
本文并不会深入底层寄存器指令与硬件等内容,只是借此主题为后续内存管理章节作扫盲,并帮助各位对分层存储体系有一个整体的把握,以及一个程序在这样的存储体系上,究竟是如何运行起来的,这些存储器在这个过程又分别扮演了什么角色。
为什么设计了分层存储体系
其实早在操作系统系列开篇的那篇文章中,我就简单介绍过分层存储体系(Memory Hierarchy),先来回顾下(这里我参考的是《现代操作系统 — 第三版》这本书,其他有些资料可能会划分的更为细致,不过在理解本文的目的上,以下划分已经足够清晰了):
各位不妨想一想,为什么需要设计出这样一个分层的存储体系来供计算机使用呢?
首先,有一个观点不用多说,每个人都希望自己的计算机拥有这样一个存储器:它容量无限大,CPU 访问它的速度无限快,并且能够永久性的存储数据(断电不会丢失数据),而且价格不能太高昂。
But,遗憾的是,现阶段的技术仍然满足不了我们的幻想。
为此,经过多年的探索,人们提出了分层存储体系的概念,把我们的幻想一个一个拆开对应到不同的存储器上。
在这个体系中,计算机拥有若干 KB 超级快速、超级昂贵且易失性的寄存器;若干 MB 快速、昂贵且易失性的高速缓存(cache);若干 GB 的速度与价格都适中、且同样易失性的内存;以及若干 TB 低速、廉价、非易失性的磁盘存储;另外还有诸如磁带等可移动的存储装置。
至于为什么这些存储器的造价不同,那就和它们的成本、材料、制作工艺等息息相关了。寄存器超级快速且超级昂贵的原因就是它和 CPU 的制作材料是相同的,所以 CPU 访问起来几乎是没有时延的。
另外,这里多提一嘴内存,关于内存的分类众说纷纭,我觉得各位对内存的概念有大体的把握就行,不必过度死扣细节。
内存也经常被人们称为主存和随机访问存储器(Random Access Memory,RAM),还有我们上文说到内存是易失性的,其实这都不是绝对正确的,只不过是通俗的说法并且被大众所认可。
现在许多计算机都已经在使用少量的非易失性随机访问存储器,也就是只读存储器(Read Only Memory,ROM),它在工厂中就被编程完毕,然后再也不能被修改。ROM 速度快并且造价低廉,很多开发商都会把用于启动计算机的引导加载模块存放在 ROM 中。
装入内存,让程序跑起来
这里我先开门见山的总结一下内存和磁盘的区别,也方便大家更好的理解下面的例子。通俗来说,内存决定了你的计算机能够同时流畅运行多少个应用程序,而磁盘决定了你的计算机能够下载安装多少个应用程序。
举个例子,这里面涉及到一个很重要的概念,各位认真看哈:
比方说你的计算机上安装了 WeChat,你双击了 WeChat 快捷方式,操作系统就会打开 WeChat 软件。
那么,各位有没有想过,在分层的存储体系上,WeChat 或者各种应用程序在你的计算机上究竟是怎么跑起来的呢?这些存储器在这个过程又分别扮演了什么角色呢?
首先,有一点你要明确,你安装的 WeChat 软件是保存在磁盘中的。软件安装的本质是什么?各位应该也都明白,就是将很多数据的集合存储到磁盘上。
双击 WeChat 快捷方式,操作系统就会知道你要运行这个软件,它会在磁盘中找到你安装的 WeChat 软件,将运行所需要的数据从磁盘中复制到内存里。注意这里!WeChat 不是直接磁盘中运行的,而是在内存中运行的。
至于原因,那当然是内存的读写速度比磁盘快得多。
所以,为了缓和磁盘之间的速度不匹配问题,程序执行前必须将硬盘上的数据复制到内存,CPU 才能够着手处理,这个过程就叫作载入内存(Load into Memory),完成这个过程需要一个不可或缺的程序:载入器或者说加载器(Loader)。
CPU 直接与内存进行交互,它会读取内存中的数据进行处理,并将结果返回并保存到内存。当然,如果你还需要将数据保存到磁盘,复制操作也会在内存和磁盘直接发生一次。
比如说,我们打开了某个 Word 文档,并输入了一些文字,虽然我们直观看到的已经发生变化了,但是磁盘中存储的文档仍然没有改变,它仍然是之前的数据,新增的文字只是暂时保存到了内存,只有我们手动保存了这篇文档比如 Ctrl + s 才会将修改保存到磁盘中。
而由于内存是易失性的,也就是说断电后数据就丢失了,所以如果你编辑完 Word 文档忘记保存或者断电导致关机了,那么你将永远无法找回这些内容(悲剧