CPU 只认内存地址,所以程序必须先被搬进内存;内存与磁盘的速度差着几个数量级,这一章就是在这道差上做文章。
第四章讲的是内存内部怎么摆,这一章把镜头拉远:看看内存外面那块又慢又大的磁盘。
一、CPU 只认内存
磁盘上的程序只是一堆字节,CPU 没办法直接照着它执行。 因为 CPU 只会干一件事:拿一个地址,去内存里取指令和数据。 它手上没有【文件】这个概念,也不认得磁盘上的目录和扇区。 所以程序要跑,第一步永远是把自己从磁盘搬进内存——这一步就叫【加载】。
二、加载这一步做了什么
最表面的动作是把可执行文件的内容复制到内存的一段连续区域里。 但搬运只是开始:还要给程序准备运行要用的东西——栈、堆,以及把里面写死的地址改成实际加载的位置。 做完这些,CPU 把 PC 指向程序的入口,程序才算真正【跑起来】。 (这些细节第八章会一条条拆开讲,这里先记住【必须搬】这一条。)
三、为什么不直接在磁盘上跑
因为速度差得太远:内存是纳秒级,机械磁盘是毫秒级。 CPU 取一条指令要几纳秒,要是每次都去问磁盘,CPU 就得干等几百万倍的时间。 所以才有那条著名的分层:CPU 缓存 → 内存 → 磁盘,一级比一级慢、一级比一级大。 每往下一层,就要多花一段等的时间——程序快不快,常常就取决于它在哪一层上卡住。
四、这一章的三个办法
既然速度差是根本矛盾,那就只能在它身上做文章,一共三条路: 少去磁盘——把读过的数据在内存里留一份(磁盘缓存,5.2)。 借磁盘用——内存不够时,把暂时用不上的部分挪到磁盘上(虚拟内存,5.3)。 换个不慢的磁盘——用没有机械动作的固态硬盘(5.4)。 剩下的两节回到程序自己:怎么少占内存(5.5),以及机械磁盘到底慢在哪(5.6)。
五、动手 Demo:程序加载到内存后才能运行
磁盘上的程序只是一堆字节,CPU 读不了它。 必须先搬进内存,CPU 才能按地址一条条取指令。
# 磁盘:约 150 MB/s,内存:约 10000 MB/s
mb = 100
for name, speed in (("内存", 10000.0),
("固态硬盘", 2000.0),
("机械硬盘", 150.0)):
print("%s 载入 %d MB 要 %.2f 秒" % (name, mb, mb / speed))
实跑输出:
--------------------------------------------------------------------
程序加载到内存后才能运行
--------------------------------------------------------------------
**磁盘上的程序只是一堆字节,CPU 读不了它。**
必须先搬进内存,CPU 才能按地址一条条取指令。
拿一个 100 MB 的程序试试,三种介质各要多久:
介质 大致速度 载入 100 MB 要多久
--------------------------------------------------
内存 约 10000 MB/s 约 0.01 秒
固态硬盘 约 2000 MB/s 约 0.05 秒
机械硬盘 约 150 MB/s 约 0.67 秒
同一份 100 MB,从内存拿和从机械硬盘拿差了 67 倍。
再看一个真实的量级感受——**在内存里造 100 万个格子**:
申请到的字节数 1000000
这个对象本身占 1000057 字节
访问第 999999 个 0(一步到位,跟访问第 0 个一样快)
**这就是为什么【启动一个软件要等几秒】:**
等的不是算,是搬——**CPU 一旦拿到代码,跑起来是很快的。**
同样一份 100 MB,内存拿和机械硬盘拿差了 67 倍。 启动软件时那几秒,等的是搬,不是算。
30 秒实验
- 算一算你的操作系统开机时要从磁盘读多少数据,按 150 MB/s 要多久。
- 想想为什么程序第一次打开总是比第二次慢。
常见误区
- 以为程序可以放在磁盘上直接跑。CPU 只认内存地址。
- 以为加载就是单纯的复制。还要准备栈、堆并修正地址。
自测三问(点开对答案)
1. 为什么程序必须先加载到内存? —— CPU 只能按内存地址取指令和数据,它不认识磁盘上的文件。 2. 加载这一步除了复制还做了什么? —— 还要准备栈和堆等运行环境,并把程序中写死的地址改成实际加载的位置。 3. 内存和磁盘的速度差多少? —— 内存是纳秒级、机械磁盘是毫秒级,相差约百万倍。- ☐ 下一节(5.2 提高磁盘访问速度的磁盘缓存)
相关笔记
- 提高磁盘访问速度的磁盘缓存 — 第一条路:少去磁盘
- 将磁盘当成内存使用的虚拟内存 — 第二条路:借磁盘用
- 内存的物理结构十分简单 — 程序要搬去的那个地方
- 🖥️ 服务器工作原理 · 索引 — 服务器怎么攒出来的
- ⚙️ 程序是怎样跑起来的 · 索引