目录
内存管理的概念

进程的内存映像

程序的装入与链接
编译是将人类可读的高级语言源代码,通过预处理、语法分析、指令翻译与汇编,转换为计算机可识别但依赖未完全解析的二进制机器指令片段的过程。
链接是将一个或多个编译生成的目标文件,结合依赖的库文件,通过合并二进制段、解析符号依赖、绑定指令地址,最终生成包含完整运行逻辑、可被操作系统识别的完整二进制可执行文件的过程。
装入是操作系统将外存中已链接生成的可执行文件,通过分配物理内存、拷贝二进制数据、虚拟地址到物理地址的转换及内存权限保护,加载到主存中,使 CPU 能够直接读取并执行的过程。

编译 - 链接 - 装入是源代码最终变成内存中可执行程序的完整流程。
装入
程序运行依赖逻辑地址,CPU 执行依赖物理地址。
物理地址是内存芯片中实际存储单元的唯一编号,具有唯一性和固定性,CPU 可直接通过它访问内存数据 。逻辑地址是程序编写、编译、链接阶段使用的虚拟地址,与物理内存的实际位置无关,需通过地址转换才能映射到物理地址。
程序运行时,CPU 只能识别物理地址,但程序本身只有逻辑地址 ------ 如果直接用逻辑地址访问内存,会找不到对应存储单元,所以需要转换。



链接
链接的核心是整合指令片段与依赖库,生成完整可执行程序, 按照库的最终绑定时机,可分为静态链接、装入时动态链接、运行时动态链接:
静态链接
- 在 编译链接阶段,链接器直接将程序依赖的库代码完整拷贝到目标文件中,与程序自身的指令、数据合并,最终生成包含所有运行所需代码的独立可执行文件。
- 链接动作在程序被装入内存前就完全完成,可执行文件与库代码绑定为一体,后续运行不再依赖任何外部库。
- 其移植性极强,运行时无依赖报错风险,执行效率高(无需额外加载库)。但可执行文件体积大,库更新后必须重新编译链接无法共享更新。
装入时动态链接
- 编译链接阶段仅在可执行文件中记录依赖的动态库路径 + 符号信息(不拷贝库代码),当程序被装入内存(启动)时,操作系统的加载器会自动找到对应的动态库,将其加载到内存,同时完成符号解析和地址绑定,让程序与库建立关联后再开始执行。
- 链接动作发生在装入阶段,可执行文件依赖外部动态库,但绑定时机在启动前,启动后运行时无需再处理库依赖。
- 其可执行文件体积小,多程序可共享同一份内存中的库,库更新后无需重新编译程序(替换动态库即可)。但移植性弱,启动速度略慢于静态链接,是日常最常用的动态链接。
运行时动态链接
- 编译链接阶段仅记录动态库的接口信息,程序 装入内存启动后 仍不加载依赖库,直到程序执行到 需要调用库中函数 / 数据的代码时,才通过系统调用动态加载库文件,解析符号并绑定地址,调用完成后还可释放库资源。
- 链接动作推迟到运行时实际调用,是装入时动态链接的进阶变种,核心是**按需加载,**编程复杂度略高。
对换与覆盖
对换和覆盖是 早期计算机的核心内存扩充技术 ,核心目标都是用外存空间弥补物理内存不足,但实现逻辑、粒度完全不同:对换是进程级整体交换,覆盖是程序内模块级局部替换。
对换



覆盖


连续分配存储管理方式
连续分配是最早、最基础的存储器管理方式 :程序被装入内存时,操作系统会为其分配一块连续的物理地址空间,程序的代码段、数据段、栈段等在物理内存中紧密排列,无其他程序的内存空间插入。
其物理地址连续,无需复杂的地址映射,但受限于连续空间的要求,存在内存利用率低、碎片多等问题。
单一连续分配

固定分区分配


动态分区分配

数据结构

动态分区分配算法





分配回收

分页存储管理方式
分页存储管理方式是操作系统中离散分配类的存储器管理技术 ,核心是将进程的逻辑地址空间 和物理内存空间 均划分为固定大小的页 ,通过页表建立逻辑页与物理页框的映射,以内部碎片 为代价,换取无外部碎片、高内存利用率。
基本方法
- 页面 :将用户程序的逻辑地址空间 划分为固定大小的页面,每个页面大小相等。
- 页框:将物理内存划分为与页面大小完全相同的页框,页框是内存的最小分配单位。
- 核心逻辑:程序的页可以离散地装入内存的页框中,不要求连续,从而解决连续分配的外部碎片问题。
分页系统中,逻辑地址 被拆分为页面号 +页内偏移 两部分,物理地址 同样拆分为页框号 +页内偏移两部分。




地址转换
虽然进程的各个页面是离散存放的,但是页面内部是连续存放的。


地址变换机构
基本的地址变换机构


在没有快表的情况下,基本地址变换机构需要访问两次内存:
- 第一次内存访问 :访问页表所在的内存 。硬件根据逻辑地址拆分出页号,结合页表寄存器中的页表起始地址,到内存中读取页表项,获取对应的物理块号。
- 第二次内存访问 :访问目标数据 / 指令所在的物理内存。用物理块号 × 页面大小 + 页内偏移合成物理地址,然后访问该物理地址对应的内存单元,读取数据或指令。
具有快表的地址变换机构
快表(TLB )是一种位于CPU 内部 的硬件高速缓存(相联存储器) ,用于缓存分页存储管理中近期常用的页表项,以加速逻辑地址到物理地址的转换过程,减少对内存中页表的访问开销。
快表和 Cache虽然都是 CPU 内部的高速缓存 ,但两者的缓存对象、作用场景、关联环节完全不同 ------ 简单说:TLB 是地址转换的缓存,服务于地址转换,Cache 是数据 / 指令的缓存,服务于内存访问。



两级页表
二级页表是一级分页存储管理的优化方案 ,核心是把原本庞大的一级页表再拆分成更小的页表,通过两级索引减少页表占用的内存空间 ,解决一级页表占用连续内存大、浪费严重的问题。
一级页表有个明显问题:页表本身太大,且需要连续的物理内存存放。

这意味着:每个进程都要占用 4MB 的连续物理内存存放页表------ 哪怕进程本身只有 1KB(只需要 1 个页面),也得分配 4MB 连续内存存页表,这是巨大的浪费。而且系统中同时运行多个进程时,要分配多个 4MB 连续内存,难度也很大。



- 多级页表中,各级页表的大小不能超过一个页面。若两级页表不够,可以分更多级。
- N级页表的访存次数(假设没有快表机构)访问一个逻辑地址需要 N+1 次访存。
分段存储管理方式

分段系统的逻辑地址结构由段号(段名)和段内地址(段内偏移量)所组成:

段号段内地址段号的位数决定了每个进程最多可以分几个段,段内地址位数决定了每个段的最大长度是多少。


- 页是信息的物理单位。分页的主要目的是为了实现离散分配,提高内存利用率。分页仅仅是系统管理上的需要,完全是系统行为,对用户是不可见的。段是信息的逻辑单位。分段的主要目的是更好地满足用户需求。一个段通常包含着一组属于一个逻辑模块的信息。分段对用户是可见的,用户编程时需要显式地给出段名。
- 页的大小固定且由系统决定。段的长度却不固定,决定于用户编写的程序,所以在进行地址变化的时候需额外根据段表中记录的段长来判断段内地址是否越界。
- 分页的用户进程地址空间是一维的,程序员只需给出一个记忆符即可表示一个地址。而分段的用户进程地址空间是二维的,程序员在标识一个地址时,既要给出段名,也要给出段内地址。
- 分段比分页更容易实现信息的共享和保护,只需要让各个进程的段表项指向同一个段即可实现共享,因按照逻辑模块划分,所以更易实现信息的共享和保护
段页式存储管理方式




🍑🍑🍑...