计算机操作系统-内存管理

分配回收

内存中哪里可以放?怎么选?怎么收回结束的进程?
传统的存储管理方式:

连续分配

分配区域没有被进程使用的部分,称内部碎片
分配区域没有进程能使用的部分,称外部碎片

单一连续分配
优点:没有外部碎片,可以不用内存保护,采用覆盖技术
缺点:(进程没用上的)内部碎片,仅能单用户,单任务效率很低

固定分区分配
支持多道程序
在这里插入图片描述
分区大小相等:死板,适用于控制多个相同对象(工厂生产)
分区大小不等:灵活,按需划分
每个分区只装入一道作业,使用==分区说明表(按大小排列)==记录,进程找到第一个能满足大小的未分配分区,记得修改分区说明表的状态

分区号大小(MB)起始地址状态
1yx未分配
2zx+y未分配
3nx+y+z未分配

实现简单,外部碎片 × \times ×
进程过大时装不下(可以使用"覆盖" 技术抢救一下),但内部碎片 \sqrt{} 效率 × \times ×

动态分区分配
支持多道程序,又称为 可变分区分配 :进程装入内存时根据进程大小动态地建立分区,分区大小和数量可变

数据结构空闲分区表     和    空闲分区链表

分区号大小(MB)起始地址状态
1ls未分配
2ms+l+x未分配
3ns+l+x+m+y未分配
大小
地址
状态
大小
地址
状态
大小
地址
状态

表项的排列顺序和动态分区分配算法有关,分配后记得修改相应表项状态
回收时只要有相邻空闲区就会合并
内部碎片 × \times ×     外部碎片 \sqrt{}
可以通过 紧凑(或拼凑,Compaction) 技术,“平移”进程块来解决外部碎片的问题

动态分区分配算法

算法数据结构优点缺点
首次适应算法(First Fit) \sqrt{} 地址排序
低到高
第一个
算法开销小
回收不用再排序
综合性能最佳
从头开始–>
低地址很多外部碎片–>
查找开销
最佳适应算法(Best Fit) × \times ×空间排序
小到大
第一个
保留大分区越来越多
外部碎片
算法开销大
最坏适应算法(Worst Fit) × \times ×
(或“最大适应算法”)
空间排序
大到小
第一个
较少外部碎片消耗大分区
大进程不友好
算法开销大
邻适应算法(Next Fit) × \times ×FF算法+循环
从上次查找结束
的位置继续查找
小进程同BF高址留大大进程同WF装不下

非连续分配

支持多道程序的 固定分区分配 和 动态分区分配分别会产生内部碎片 和 外部碎片,“紧凑”算法代价很高----->内存分为分为多个大小相等的小分区,再按分区大小拆分进程,实现非连续内存空间存储,分区越小内部碎片越小

基本分页存储管理

内存
每个分区称为页框、页帧、内存块、物理块(多数4KB)
每个都有号码(页框号、页帧号、内存块号、物理块号)
进程
被分为与页框大小相等页(或页面)物理单位
对应的号码为页号
访问过程

逻辑地址
计算页号
查询
页的起始地址
计算 页内偏移量
物理地址=页起始地址+页内偏移量

其中假设地址32bit,页面4KB=212B,按字节寻址逻辑地址

页号页内偏移量
31~1211~0
220-1<3Byte使用2的整数幂做页面大小方便计算

每个进程创建一张页表(慢表)

页号 =页表起始地址 + 页号 × \times × 3Byte (顺序存储+表项等大=隐藏)物理块号(页框号)

表项按页号顺序存储,每页可存 4 K B = 1365 × 3 B + 1 B 4KB= 1365\times3B+1B 4KB=1365×3B+1B
但为了方便查表,常使用4B存储一个表项(没有内部碎片1B)

两级页表
一个进程最大220个页面,页表大小 = 222B = 210 × \times × 4KB,需要1024个连续的页框才能存下
局部性原理:一段时间内集中访问若干页面–>其他页面不用常驻内存
再分组:为离散分配的页表再建 “页目录表” (or 外层页表 or 顶层页表)

一级页号二级页号页内偏移量
31~22 (210)21~12 (210)11~0 (212)

基本地址变换机构
逻辑地址 转换 物理地址 的一组硬件机构
在这里插入图片描述
快表
时间局部性:被执行的指令很可能再次被执行,被访问数据很可能再次被访问(循环指令)
空间局部性:被访问存储单元附近的单元很可能近期被访问(数组)
局部性原理 导致多次重复查询同一页号 + 高速缓冲寄存器(cache) = 快表 (TLB,Translation Lookaside Buffer)
在这里插入图片描述
命中则只需要“取数据”仅次内存访问,未命中则需要"慢表查询”+“数据访问"次内存访问
“快表”溢出需要用算法找出可以替换的页表项

基本分段存储管理

逻辑单位 进程地址划分为若干段(编译器:段名–> 基址),每段占用一个连续空间,逻辑地址:

段号段内地址

段表

段号(顺序存储+表项等大=隐藏)段长基址
2段号位2段内地址位内存地址空间4GB=232B

同样可以使用"快表"
在这里插入图片描述

基本段页式存储管理

基本分页存储基本分段存储管理
一个逻辑地址=一个物理地址(一维)段名+段长(二维)
物理单位,系统行为逻辑单位,用户行为
大小固定=无外部碎片容易实现信息的共享保护
信号量机制 等“可重入”/“纯” 代码
保护部分和共享部分在页内分不开大小可变=长段没”坑“,有外部碎片

段页式管理 = 逻辑分段+每段分页 ,从而同时获取两种管理方式的优点

用户指定

段号段内地址

系统根据段内地址分配 页号 与 页内地址 得到逻辑地址

段号页号页内偏移量

段表

段号(顺序存储+表项等大=隐藏)页表长度物理块号(页框号)

页表

页号(顺序存储+表项等大=隐藏)物理块号(页框号)

在这里插入图片描述
三次内存访问,引入快表{段号;页号;物理地址}可以减少至一次

空间扩充

覆盖与交换

覆盖: (同一个进程中)程序按功能分段(模块)
用户必须指明覆盖的结构,增加用户负担
在这里插入图片描述
交换: (不同进程间)就是中级调度,换出空间需求大的进程,换入需求小的进程
由就绪态 转换为 就绪挂起时,PCB还是常驻内存中
内存吃紧时,降低系统负荷,反映在缺页率在这里插入图片描述

虚拟内存

局部性原理 + 高速缓冲技术

传统的存储管理机制虚拟内存技术
作业一次性装入内存
大程序无力,并发度下降
多次性
访问的局部性
驻留性 --> 浪费资源
对换性

实际容量=min(内存+外存,最大容量=2CPU寻址位数)
操作系统提供 请求调页/请求调段+页面置换/段置换 功能

请求分页存储管理

页表增加了页面状态的描述字段

页号(顺序存储+表项等大=隐藏)物理块号(页框号)状态位访问字段修改位外存地址
始址+页号 × \times ×表项大小物理地址内存中?访问次数
访问时间
被写?文件结构

在这里插入图片描述
表中有省略
被“挤出快表”(从快表中删除)的表项要在慢表中修改相应的表项
被”写“过的表项“修改位”变化,没被写过的表项“置换”时可以不用拷贝回外存
I/O操作慢,频繁置换开销很大
在这里插入图片描述

页面置换算法

挑选 “内存中暂时用不到的块” 换出到外存,好的算法缺页率低,磁盘I/O少
缺页率= 缺 页 次 数 总 访 问 次 数 \frac{缺页次数}{总访问次数} 访

最佳置换算法(Opt,Optimal)
淘汰最长时间内不会再使用的页面

访问顺序70120304230321201701
内存块07772-2-2--2--2---7--
内存块1-000-0-4--0--0---0--
内存块2--11-3-3--3--1---1--
缺页统计-----------

7号页面之后出现时间最晚,被换出,其他类推
缺页率= 9 20 \frac{9}{20} 209=45%
无法预知页面访问顺序无法实现,作为比较基准

先进先出置换算法(FIFO)
淘汰最早进入的页面

访问顺序321032432104
内存块03330004--44-
内存块1-222333--11-
内存块2--11122--20-
缺页统计---

3号页面最早出现,被换出,其他类推
缺页率= 9 12 \frac{9}{12} 129=75%
增加内存块数可能导致某些访问顺序( 如上 )会出现Belady异常(缺页率反而变大)
最先进入的通常为常驻块( 如main函数等 )
性能最差

最近最久未使用置换算法(LRU,least recently used)
淘汰最早开始没有被使用的已驻页面

页号(顺序存储+表项等大=隐藏)物理块号(页框号)状态位访问后计时修改位外存地址
访问顺序18178272183821317137
内存块011-1-1----1-----1---
内存块1-8-8-8----8-----7---
内存块2---7-7----3-----3---
内存块2-----2----2-----2---
缺页统计--------------

7号页面最早开始没有被使用,被置换
缺页率= 6 20 \frac{6}{20} 206=30%
性能最好,但开销大,需要硬件支持

时钟置换算法(CLOCK)
又称“最近未使用算法(NRU,Not Recently Used)”
被访问置1,需要置换时,(最多2圈)循环检查并置零访问位,淘汰访问位0的页面

页号(顺序存储+表项等大=隐藏)物理块号(页框号)状态位访问位修改位外存地址

在这里插入图片描述

改进型时钟置换算法
在时钟置换算法基础上,不改变修改位状态,访问位相同时优先淘汰没有被修改过的页面
未修改 = 不用回写磁盘 = 节省时间

页号(顺序存储+表项等大=隐藏)物理块号(页框号)状态位访问位修改位外存地址
---(00)-

第一轮:找(0,0) = {没访问,没修改}
第二轮:没找到(0,0)就找(0,1) = {没访问,有修改},置0访问位
第三轮:没找到(0,1)就找(0,0) = {有访问,没修改}
第四轮:没找到(0,0)就第一个(0,1) = {有访问,有修改}
替换以上步骤找到的页面
在这里插入图片描述
性能最均衡

页面分配策略

驻留集:系统分配给进程的物理块集合(采用虚拟存储技术的系统 驻留集 < 进程大小)

.局部置换(自身物理块)全局置换(空闲 或 其他进程非核心物理块)
驻留集大小不变 = 固定分配固定分配局部置换
驻留集大小可变 = 可变分配可变分配局部置换可变分配全局置换

固定分配局部置换:根据进程大小、优先级等参数确定驻留集
可变分配局部置换:根据缺页率动态调整驻留集大小,只能置换自己的页
可变分配全局置换:只要缺页一定得到新的物理块,先找空闲块,再找其他进程非核心(未锁)块

调入时机
1.预调页:= 空间局部性预测,或用户指定,主要用于首次调入(运行前调入)
2.请求调页 = 缺页 才 调页,磁盘IO开销大

调入源头
在这里插入图片描述
抖动(颠簸):同一个页面频繁的换入换出内存
原因可能是驻留集不够,导致频繁访问的页面放不下,催生出了 = = 》
(Denning)工作集某段时间内(窗口尺寸) 进程实际访问的页面集合
根据工作及调整驻留集大小(驻留集<工作集 便会抖动),或置换驻留集中的非工作集页面

请求分段存储管理

请求段页式存储管理

地址转换

编译
链接
编译
链接
装入程序
链接
source.cpp
目标模块.obj
地址 0-49
装入模块.exe
完整逻辑地址 0-99
source.cpp
目标模块.obj
地址 0-49
内存
起始地址+逻辑地址
库文件.lib

相对地址=逻辑地址
绝对地址=物理地址

寻址空间 = 2地址总线位
寻址范围 = 0x00 ~ 内 存 大 小 字 大 小 \frac{\tiny 内存大小 }{\tiny 字大小}
按字节寻址
存储单元 = 1Byte = 8 bit =最小的编址
按字寻址
存储单元 = 1 Word = ( 16 / 32 / 64 ) 8 \frac{(16 / 32 / 64)} { 8 } 8(16/32/64) Byte

链接方式

得到完整的逻辑地址
静态链接
链接—>(.exe)—>装入—>内存
装入动态链接
(.obj)—>装入+链接–>内存
运行动态链接
运行时—>需要(.obj) or (.lib) —>链接—>内存
可以共享模块,易于修改

装入方式

地址的转换:逻辑地址—>物理地址
绝对装入
(.cpp){逻辑地址} —> 编译 —> (.obj){物理地址}
单道程序环境
静态重定位
又称 可重定位装入
(.cpp){逻辑地址} —> 编译 —> (.obj){逻辑地址} —> 装入 —> 内存{物理地址}
要求连续全部内存空间,运行期间更不可移动!
多道批处理系统
动态重定位
又称 动态运行时装入
(.cpp){逻辑地址} —> 编译 —> (.obj){逻辑地址} —> 装入 —> 内存{逻辑地址} —> 执行时

起始地址
重定位寄存器
逻辑地址
+
物理地址

允许进程移动,分配不连续存储区,可以共享程序段!!
现代操作系统

存储保护

保证进程互不干扰
方法一:cpu{上下限寄存器}
方法二:

逻辑地址
最大逻辑地址
起始物理地址
CPU
越界?
界地址寄存器
限长寄存器
越界异常
+
重定位寄存器
基址寄存器
实际物理地址
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验内容: 编写一个动态分区分配算法模拟程序,加深对动态分区存储管理方式及其实现过程的理解。 要求: 1.空闲通过空闲进行管理,在内存分配时,优先考虑低地址部分的空闲。 2.分别采用首次适应算法、最佳适应算法和最坏适应算法模拟内存空间的动态分配与回收,每次分配和回收后显示出空闲链的详细情况(说明:在申请不成功时,需要打印当前内存的占用情况信息)。 3.进程对内存空间的申请和释放可由用户自定义输入。 4.参考请求序列如下: (1) 初始状态下可用内存空间为640KB; (2) 进程1申请130KB; (3) 进程2申请60KB; (4) 进程3申请100KB; (5) 进程2释放60KB; (6) 进程4申请200KB; (7) 进程3释放100KB; (8) 进程1释放130KB; (9) 进程5申请140KB; (10) 进程6申请60KB; (11) 进程7申请50KB; (12) 进程6释放60KB。 测试用例格式如下: 输入: 动态分区分配算法选择 可用内存空间容量 序号/进程号/申请或释放操作/申请或释放的容量 其中: (1) 动态分区分配算法:1----首次适应,2----最佳适应,3----最坏适应 (2) 申请或释放操作: 1----申请操作,2----释放操作 输出: 序号/内存空间状态1/内存空间状态2...... 内存空间状态表示分为两种情况: (1) 内存空间被占用: 内存空间起始地址-内存空间结束地址.1.占用的进程号 (2) 内存空间空闲 内存空间起始地址-内存空间结束地址.0

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值