目录儿
- 三、内存管理
- 3.1 内存管理基础
- 3.1.1存储器的多层结构
- 3.1.2 进程运行基本原理
- 进程的装入
- 3.1.3 内存扩充
- 3.1.4 内存的分配
- 3.1.4.1连续分配
- 3.1.4.2非连续分配
- 3.1.4.2.1基本分页存储管理
- 3.1.4.2.2基本分段存储管理
- 3.1.4.2.3 段页式管理
- 3.2 虚拟内存管理
- 3.2.1 虚拟内存的概念
- 3.2.2 虚拟内存的实现
- 3.2.2.1 请求分页管理
- 3.2.2.2 页面置换算法
- 3.2.2.3 页面分配策略
三、内存管理
3.1 内存管理基础
3.1.1存储器的多层结构
在计算机中,以CPU的调度距离为准,从近及远对不同的存储器划分出多个层级。
进程挂起就是放在硬盘缓存里。
高级缓存是一个独立硬件,存在于CPU里面。效率比寄存器慢比内存快。
3.1.2 进程运行基本原理
进程的装入
程序保存在磁盘中,经过编译、链接后生成一个 装入模块(编译后的代码和数据),然后经由 装入程序 把这个 装入模块 加载进内存的过程称为 装入。装入后就是一个进程。
装入分为三种:
- 绝对装入:给装入模块分配的是绝对物理地址,不能变动,适合单道程序环境。
- 可冲定位装入:给装入模块分配初始逻辑地址(通常是从0开始的),装入过程如果发现逻辑地址中指向的物理地址被占用,则把物理地址往后顺延,然后修改逻辑地址指向,再装入。(逻辑地址指向的物理地址重定向了)
- 动态运行时装入:程序的装入不再是一次性装入,先装入核心程序(静态上下文),在程序运行过程中需要分配新资源(动态)时再链接装入内存,此时装入的装入模块和程序上一次装入的模块并不是挨在一起的,是分散的。
- 以上三种装入方式都是随着计算机发展,程序越来越大、越来越复杂而一步步进化的。
- 链接是一个过程,因为程序中一般都调/使用了各种各样的库(函数库、类库等),链接程序把库和编译后的程序(也叫目标模块)封装成一个装入模块的过程就是链接。
- 程序所有数据一开始默认分配的物理地址都是0。
- 内存保护就是进程地址保护,保护进程起始地址和结束地址之间的内存空间不受侵扰。
3.1.3 内存扩充
当内存加载一个新的进程,但是空间不足的时候,操作系统会通过内存扩充技术解决这个问题。
内存扩充有两种方式:
- 覆盖:从内存中划分出一块空间(覆盖区),覆盖区内的进程和数据可以被覆盖,可以动态变化的。
- 交换:从硬盘上划分一块空间(硬盘缓存),把较不活跃的进程交换到外存中,再把新的进程加载进内存。
3.1.4 内存的分配
内存分成系统区和用户区两大部分,用户进程就放在用户区中。
3.1.4.1连续分配
- 单一连续分配(单一进程)
- 优点
- 实现简单
- 无外部碎片(没有分配给此进程以外的进程或数据的内存空间)
- 不一定需要内存保护(隔离保护系统区和用户区)
- 缺点
- 只能用于单用户、单任务OS
- 有内部碎片(分配的整个内存空间没有利用完)
- 存储器利用率低(只有一个进程在用)
- 优点
- 固定分区分配
- 优点
- 实现简单
- 无外部碎片
- 缺点
- 较大用户程序时,需要采用覆盖技术,降低了性能
- 会产生内部碎片,利用率低
- 优点
- 动态分区分配
- 记录内存使用情况:
- 空闲分区表:
- 空间分区链
- 空闲分区表:
- 分区选择算法
- 首次适应算法:从低地址查找合适空间
- 最佳适应算法:优先使用最小空闲空间
- 最坏适应算法:优先使用最大连续空间
- 临近适应算法:从上次查找处向后查找
- 记录内存使用情况:
3.1.4.2非连续分配
3.1.4.2.1基本分页存储管理
通过页表映射程序的逻辑地址与内存的物理地址,页表保存在进程控制块中。
基本地址变换机构(硬件):
- 页式管理中地址空间是一维的
- 每次访问内存都需要地址转换,因此必须足够快
- 页表不能太大,会降低内存利用率
具有快表的地址变换机构:
- 直接将页号与快表页号比较
- 匹配成功,取块号+偏移量形成地址
- 匹配失败,访问主存页表,并同步到快表(局部性原理)
- CPU在对某个变量进行 +1 操作,实际上会访问内存两次。第一次是访问页表获取块号,然后计算出物理地址后,再去访问内存中变量的内存地址。这就引发一个效率问题,因此通常会把本次查询的页表的那个条目加载进cpu的缓存中,提升(下次)查询的效率。
- 内存中的页表称为慢表,高速缓存中的页表(条目)称为快表。
- 快表是慢表数据的一部分(高速缓存空间很珍贵)
- 比一个32位的机器上(一次能处理的最大位数为32),内存块(页框)大小为4k(212),也就是内存块占据了12位,前面20位分配给了页号,所以页号最大约为220(约1,000,000),也就是这个页表的最大条目数约为1,000,000条。
两级页表:
页表是一个数组,占用大量连续空间,而且在访问的过程中一段时间内只访问页表的一小部分,所以引申出二级页表的概念,把大页表再拆分。
- 将逻辑地址拆分成三部分(原本是两部分)
- 从PCB(进程控制块)中读取页目录表始址
- 根据一级页号查出二级页表位置
- 根据二级页号查内存块号,加偏移量计算物理地址
3.1.4.2.2基本分段存储管理
分页存储是把物理内存按照一定大小进行划分,分段存储是把用户进程进行划分,把你个进程划分成主程序、子程序。因此进程的每个分段的大小不一。
在32位计算机中,16位(64k)分配给段号,16位分配给段内地址。
- 分页与分段对比:
- 分页划分物理内存,分段划分用户进程。
- 页->物理单位
- 段->逻辑单位
- 分页->一维地址空间
- 分段->二维地址空间
- 分段更容易信息共享和保护
- 因为段表一般很小(一个进程分不了几个段),通常放在段表寄存器中。
- 每个进程的分段编号都从0开始
3.1.4.2.3 段页式管理
单独把分页和分段拎出来都有其突出的缺点
因此后来的发展方向是把二者结合取其精华去其糟粕。
页表地址就是页表存放块号。
段页表查询流程:
管理方式:
▶ 先分段,再分页
▶ 个进程->1个段表
▶ 1个段表项->1个页表
▶ 1个页表->多个物理块
3.2 虚拟内存管理
3.2.1 虚拟内存的概念
内存 + 外存 = 虚拟内存,是一个逻辑概念。
- 特征
- 多次性:进程在虚拟内存中是多次加载而不是一次性加载完成的。
- 对换性:进程在内外存之间存在迁移、换入换出的特性。
- 虚拟性:虚拟内存是对内存容量扩充的一个逻辑概念。
3.2.2 虚拟内存的实现
3.2.2.1 请求分页管理
进程在运行中因为缺页等原因动态从外存或磁盘中请求加载(掉入)文件和数据。
页表:
🔸状态位P:表示页指向的数据(块)是否已经调入内存(0否1是)
🔸访问字段A:记录一段时间内块被访问的次数
🔸修改位M:表示块内数据是否被修改过(0否1是)
🔸外存地址:资源在外存中的地址
缺页中断:
通过中断加载相关页到内存,属于内中断。
页面置换:
通过中断把闲置页置换到外存中,属于内中断。
调页过程的寻址过程:
① 请求调页,判断是否在内存
② 如果内存空间不足,可能需要页面置换
③ 新增/修改页表项(页表有记录则修改,没记录则新增)
④ 把新加载的表项作为热点表项同步到快表
3.2.2.2 页面置换算法
3.2.2.3 页面分配策略
- 固定分配局部置换:为每个进程分配一组固定数量的物理块,进程运行时不再改变。若发生缺页,从分配的N个页面中选出一页换出,调入下一页。
- 可变分配全局置换:进程运行时,根据情况增加或减少物理块。发生缺页时,从空闲物理块取出一块分配给该进程,仅当所有物理块都用完时,OS才从内存中选择一页调出。
- 可变分配局部置换:分配固定内存,由进程本身置换,当操作系统发现置换频率大时,再分配额外的内存给进程;
驻留集:驻留在内存中的页数
- 进程在主存中的页数越小,错页率越高,反之越低
- 进程在主存中的页数越小,可容纳的进程数越小,反之越高
资料来源:
- 哔哩哔哩 马士兵教育 马士兵-小森 清华大牛耗时1000分钟把计算机底层知识 | 计算机组成原理 | 操作系统 | 数…
https://www.bilibili.com/video/BV1qe4y1T7t3?p=81&spm_id_from=pageDriver&vd_source=c2e346bb74807b3fde142d31e57292ce