【操作系统核心详解】段式存储与页式存储:区别、碎片及虚拟内存的本质
1. 引言:为何需要内存管理?
在单道程序的早期计算机中,一个程序独占所有内存。但现代操作系统需要同时运行多个程序,如何让这些程序高效、安全地共享有限的内存资源?这就引出了内存管理的核心概念:分段 和 分页。
它们都旨在更高效地利用内存,但设计的视角和目的截然不同。简单来说:
- 分段是逻辑上的划分,面向程序员。
- 分页是物理上的划分,面向操作系统和硬件。
本文将深入解析两者的区别,并探讨与之相关的碎片问题及虚拟内存的实现原理。
2. 段式存储:像一本书的章节
2.1 什么是分段?
分段是对程序逻辑结构的直接映射。一个程序被自然地划分为若干个段,例如:
- 代码段 (.text):存放程序指令,只读。
- 数据段 (.data):存放已初始化的全局变量,可读可写。
- BSS段 (.bss):存放未初始化的全局变量,可读可写。
- 堆栈段 (Stack/Heap):用于函数调用和动态内存分配。
每个段在内存中占据一块连续但大小不固定的空间。
2.2 地址变换与段表
逻辑地址在分段系统中是一个二维地址,表示为 (段号s, 段内偏移w)
。
地址变换过程:
- 系统通过控制寄存器找到段表的起始地址。
- 以
段号s
为索引,查找段表中的对应表项,获得该段的基址(起始物理地址)。 - 将段基址与段内偏移w相加,得到最终的物理地址。
注意:在实际系统中,段表项还包含段长信息,用于越界检查,防止访问不属于该段的内存。本文例题为简化模型,暂不进行此检查。
3. 页式存储:像把内容印在标准稿纸上
3.1 什么是分页?
分页是对物理内存的机械式划分。它将进程的地址空间和物理内存都切分成固定大小的小块。
- 进程中的块称为 “页”
- 物理内存中的块称为 “页框” 或 “块”
页的大小由系统决定,通常是4KB。分页对程序员是透明的,你感觉不到它的存在。
3.2 地址变换与页表
逻辑地址在分页系统中是一个一维地址,系统会将其自动解释为 (页号p, 页内偏移d)
。
地址变换过程:
- 系统通过控制寄存器找到页表的起始地址。
- 以
页号p
为索引,查找页表中的对应表项,获得对应的物理块号f。 - 将物理块号f与页内偏移d拼接,得到最终的物理地址(计算公式:
物理地址 = f × 页面大小 + d
)。
4. 核心区别对比:一张图看懂
维度 | 段式存储 | 页式存储 |
---|---|---|
本质/视角 | 逻辑单位,反映程序结构 | 物理单位,机械划分 |
划分对象 | 程序的地址空间 | 程序的地址空间和物理内存 |
大小 | 可变长 | 固定大小 |
地址空间 | 二维地址 (段号, 段内偏移) | 一维地址 (页号, 页内偏移) |
碎片问题 | 产生外部碎片 | 产生内部碎片 |
对程序员可见 | 可见,可能需要考虑段 | 透明,完全由系统管理 |
主要目标 | 模块化、共享、保护 | 虚拟内存、高利用率、消除外部碎片 |
管理表格 | 段表 (含段基址、段长) | 页表 (含物理块号) |
5. 碎片问题:内部碎片 vs. 外部碎片
碎片是指内存中无法被利用的闲置空间。
特征 | 内部碎片 | 外部碎片 |
---|---|---|
定义 | 已分配的内存块内部,无法被进程使用的空间 | 未分配的空闲内存之间,太小而无法利用的零散空间 |
产生原因 | 分配单元固定,进程用不满一个单元 | 分配和回收导致空闲内存被分割成不连续的小块 |
典型场景 | 分页管理(进程最后一页用不满) | 分段管理、动态分区 |
能否"紧凑" | 不能 | 能(但耗时) |
生活化类比:
- 外部碎片:像一个被各种物品占据的储物柜,虽然总空间很大,但剩下的空隙都很小,放不下一个大箱子。
- 内部碎片:像你买了一个大行李箱,但只装了一半的衣服,剩下的空间浪费了,但别人也无法使用。
6. 虚拟内存:"一次性"与"驻留性"的打破
6.1 传统内存管理的两大桎梏
- 一次性:要求进程的全部代码和数据必须一次性装入内存才能运行。
- 问题:大程序无法运行;内存利用率低。
- 驻留性:进程一旦装入内存,就会一直驻留直到结束。
- 问题:内存中充斥着很多不常用的代码(如错误处理例程),浪费空间。
6.2 虚拟内存的解决方案
虚拟内存技术正是通过打破"一次性"和"驻留性"来实现的!
-
如何打破"一次性"? -> 请求调页
操作系统只将进程当前需要的页面调入内存,其余的留在磁盘上。这使得程序可以比物理内存大得多。 -
如何打破"驻留性"? -> 页面置换
当内存空间不足时,操作系统将内存中暂时不用的页面换出到磁盘,为急需的页面腾出空间。需要时再换入。
为什么分页是虚拟内存的理想基础?
因为页是固定大小的单位,非常适合作为磁盘I/O和内存管理的单元,并且彻底消除了外部碎片。虽然分段也可以实现虚拟内存(段置换),但可变长的特性导致管理复杂,容易产生外部碎片。
7. 现代实践:段页式结合
现代操作系统(如x86 Linux)采用的是段页式结合的管理方式,博采众长:
- 先用分段:利用其保护特性。CPU仍使用段机制,确保代码段不能写入,数据段不能执行等。
- 再用分页:作为虚拟内存和物理内存管理的基础。将段映射到的线性地址空间,再通过分页机制映射到物理内存。
流程简化:
逻辑地址 -> (分段机制) -> 线性地址(虚拟地址) -> (分页机制) -> 物理地址
对于应用程序员而言,感受到的是一个巨大的、统一的虚拟地址空间,背后的复杂段页转换均由操作系统和硬件完成。
8. 总结
- 段与页:段是逻辑单位,页是物理单位。段面向程序结构,页面向内存管理。
- 碎片:分页产生内部碎片,分段产生外部碎片。
- 虚拟内存:其本质是基于分页(或段页式),通过请求调页和页面置换技术,打破了传统内存管理的"一次性"和"驻留性"约束,从而实现了在有限物理内存上运行更大、更多程序的目标。
理解这些核心概念,是掌握操作系统内存管理,乃至后续学习进程、线程、文件系统等知识的重要基石。