操作系统内存管理
一、前置基础:内存硬件常识、地址与单位、指令原理
(一)内存基础概念
1.内存作用
程序原始存储在外存(磁盘),磁盘读写速度远低于CPU运算速度;内存缓冲CPU与外存速度差,程序运行前必须将数据加载至内存,CPU仅和内存交互数据。
2.内存编址规则(类比酒店房间编号)
内存划分为若干存储单元(最小数据存放单元),从0开始顺序编号(内存地址)。
○按字节编址(考研主流):1地址=1Byte(字节),1Byte=8bit(比特/二进制位);
○按字编址:1地址=1个字,字长由题目指定(16/32/64bit不等)。
3.存储容量单位换算
1KB=210B、1MB=220B、1GB=230B;大写B=Byte字节,小写b=bit比特。
例:4GB内存、字节编址 → 总存储单元=4×230=232,需要32位二进制表示地址。
(二)CPU指令执行原理
1.高级语言(C语言)→编译→机器指令,一条指令分为操作码+地址参数
○操作码:指明CPU执行操作(传送/加法等);
○地址参数:指明数据在内存/寄存器的编号。
2.示例
X=X+1拆分为3条机器指令
①从内存取X值放入寄存器;②寄存器数值+1;③结果写回X对应的内存地址。
3.逻辑地址&物理地址由来
可执行文件(装入模块)内部指令使用逻辑地址(相对地址):相对于进程起始位置的偏移;进程装入内存的实际内存编号为物理地址。
若进程装入起始位置改变,直接使用逻辑地址会越界篡改其他进程数据,因此必须实现逻辑→物理地址转换。
(三)三种装入方式(地址转换方案,考研重点)
1.绝对装入
转换时机:编译阶段
核心特点:编译时直接生成物理地址,提前确定程序装入位置;程序更换内存起始地址就无 法运行,灵活性极差
适用场景:早期单道程序(无OS)
2.可重定位装入(静态重定位)
转换时机:程序装入内存时
核心特点:装入瞬间批量修改全部指令地址(逻辑+进程起始地址=物理);进程必须连续全量装入,运行中不能移动
适用场景:早期多道批处理OS
3.动态运行时装入(动态重定位)
转换时机: :CPU运行指令时
核心特点:硬件:重定位寄存器(基址寄存器)存放进程起始物理地址;CPU访问=逻辑地址+基址;进程可离散分配、运行中可挪动、按需分段加载
适用场景: 现代主流操作系统
二、从源代码到程序运行全流程+三种链接方式
(一)完整执行步骤
源代码(.c) →编译→目标模块(.o,各模块独立从0编逻辑地址) →链接→装入模块(EXE可执行文件) →装入内存→运行
1.编译:单文件高级语言→机器码,每个目标模块独立编址;
2.链接:整合多个目标模块+系统库函数(如printf),拼接成完整逻辑地址空间;
3.装入:逻辑地址转为物理地址,加载进内存。
(二)三种链接方式
1.静态链接:运行前全部目标模块+库打包成EXE,运行时不再拆分;
2.装入时动态链接:程序装入内存的同时,边装入边链接模块;
3.运行时动态链接:用到哪个模块才调入+链接,未调用的模块不加载进内存,节省内存、利用率最高。
三、OS内存管理四大核心功能
1.内存空间的分配与回收
OS维护内存空闲区/占用区信息;新进程分配空闲内存,进程结束回收内存空间,后续章节细讲分配算法。
2. 逻辑上扩充内存(虚拟内存思想)
物理内存容量有限,依靠虚拟技术把小物理内存拓展为大逻辑内存;落地技术:覆盖技术、交换技术、虚拟存储。
3. 地址转换(重定位)
OS负责逻辑→物理地址转换,依托三种装入方案:
•绝对装入:无OS,编译器完成;
•静态重定位:装入程序(OS组件)装入时完成;
•动态重定位:硬件寄存器+OS,运行时实时转换(现代OS)。
4. 内存保护:防止进程越界访问
目标:进程仅能访问自身内存,禁止篡改OS空间、其他进程空间。
两种硬件实现方案:
1.上下限寄存器:分别存进程物理起始、结束地址,访问地址超出范围则越界报错;
2.基址+限长寄存器(重定位+界地址):
○基址寄存器:进程起始物理地址;
○限长寄存器:进程最大合法逻辑地址;
先校验逻辑地址≤限长,合法再算物理地址=逻辑+基址,超限抛出异常。
四、32位系统进程虚拟地址空间(进程内存映像,高频考点:C变量分区存储)
32位进程独享4GB虚拟地址空间:高1GB=操作系统内核区(PCB、页表、内核代码,用户不可直接访问);低3GB=用户地址空间,自低→高分为5大区:
1.代码段+只读常量区(只读,进程启动后大小固定)
存放:程序机器指令、const修饰常变量;
⚠️宏定义常量不占内存:预处理阶段直接文本替换为立即数,嵌入指令,不在该区存储。
2. 全局/静态数据区(可读可写,大小固定)
存放:全局变量、static静态局部变量。
3. 堆区(Heap):动态分配区,向上增长
存放:malloc/free动态申请的内存;运行时动态扩容/释放。
4. 共享库映射区
存放程序调用的系统库函数(如printf),多个进程可共享同一份库代码。
5. 用户栈(Stack):向下增长
存放:函数局部变量、函数参数、函数返回地址;函数调用层数越多,栈占用越大,函数结束自动释放。
考题形式:给定一段C代码,区分各变量存储分区。
五、内存扩充技术:覆盖技术 & 交换技术
(一)覆盖技术:同一进程内部内存复用
1.出现背景:早期物理内存极小,程序总大小>物理内存;
2.原理:程序拆分为多个模块,划分固定区+覆盖区
○固定区:核心模块(main)常驻内存,全程不换出;
○覆盖区:不会同时调用的模块共用同一块内存,需要时调入、用完调出;覆盖区大小=共存模块中最大模块尺寸。
3.优缺点
✅ 大幅降低程序运行所需物理内存;
❌ 对用户不透明,需要程序员手动规划模块调用结构、声明覆盖关系,编程负担大;现已淘汰,仅老系统使用。
4.核心:覆盖发生在单个进程内部。
(二)交换技术(中级调度实现):不同进程间内存换入换出
1.原理:内存紧缺时,将内存中暂时无法运行的进程数据换至磁盘交换区;空闲后再把外存就绪进程换回内存;PCB全程常驻内存(记录进程在外存存放位置,用于管理)。
2.磁盘分区:
○文件区:存普通文件,离散分配、侧重空间利用率;
○交换区:存放换出进程,连续分配、侧重IO读写速度(进程换入换出更快)。
3.换出时机:内存资源紧张、系统缺页率飙升;
4.优先换出进程选择:①阻塞进程 ②低优先级进程;限制:驻留时间过短的进程暂缓换出,避免饥饿;
5.进程状态拓展:换出外存→就绪挂起/阻塞挂起(7状态模型);
6.核心:交换在多个不同进程之间完成。
(三)覆盖VS交换核心区别
覆盖:单进程内模块共享内存,程序员手动控制;
交换:多进程之间内外存互换,OS自动调度。
六、考点总结
1.计算题:容量单位换算、地址所需二进制位数;
2.区分三种装入、三种链接的时机、特点、适用环境;
3.C语言变量对应进程五大分区;
4.覆盖/交换的原理、优缺点、使用场景、二者区别。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)