OS-3-内存管理
2021-08-30 13:58:36 0 举报
AI智能生成
操作系统 内存管理 知识点梳理
作者其他创作
大纲/内容
内存管理的工作
内存空间分配与回收
内存空间的扩充
存储保护
保证进程在运行中互不干扰
越界时抛出越界异常
一般采用的方法
上下限寄存器
<br>
重定位寄存器(基址寄存器)+<br>界地址寄存器(限长寄存器)<br>
限长寄存器存放<font color="#F44336">最大逻辑地址</font>
基址寄存器存放<font color="#F44336">起始物理地址</font>
允许不连续装入的程序
内存空间的扩充
覆盖技术
程序分段,常用段常驻内存,<br>不常用段按需调入<br>
内存中
一个固定区
常驻段<br>一经调入不再调出<br>
若干覆盖区<br>
不常用段
按照程序逻辑,让不可能被同时访问的<br>程序段共享同一覆盖区(如同级分支)<br>覆盖区大小为较大者<br>
在进程内进行
只能由程序员声明覆盖关系
交换技术
将部分进程暂时换到外存(挂起),把外存中具备运行条件的进程换入内存<br>
PCB常驻内存
进程被保存在外存的“对换区”
“对换区”
采用连续分配方式,追求换入换出速度
IO速度更快
“文件区”
采用离散分配方式,追求存储空间利用率
在进程间进行
交换时机
进程频繁缺页
换出部分进程<br>
缺页率明显下降
停止换出<br>
系统负荷高
停止换出
交换对象
阻塞态进程
低优先级进程
可能饥饿
驻留时间长的进程
虚拟内存技术
概念
背景:传统的存储管理具有一次性和驻留性的特征<br>
基础
基于局部性原理
<br>
空间局部性
时间局部性
高速缓存技术
离散分配
基本特征
多次性<br>
作业无需一次性装入,而是分多次按需调入<br>
对换性<br>
作业运行时无需常驻内存,允许在作业运行过程中将作业换入换出
虚拟性
逻辑上扩充了内存容量,使得用户感受到的内存大于实际
基本功能<br>
页面/段置换功能:不在内存时,向OS请求将目标页/段调入内存<br>
请求换出功能:内存空间不足时,由OS将暂时不用的页/段换出
相对于一般的离散分配,根据基础<br>技术的选择,虚拟存储实现可分为<br>
请求分页存储管理
请求分段存储管理
请求段页式存储管理
请求分页管理方式的实现
页表机制
OS需要知道页面是否已经调入,以及在外存中的位置
OS需要知道当前要换出的页面是否已经修改过
相比基本页表,此页表称为请求页表
页表项的结构
内存块号
状态位
是否已经调入内存
访问字段
记录被访问次数或上次被访问的时间<br>为置换算法提供数据参考<br>
修改位
是否已被修改过
外存地址
缺页中断机构
当要访问的<font color="#F44336">页面不在内存</font>中,产生缺页中断,并阻塞。
缺页中断是一种内中断<br>
请求OS的缺页中断程序处理,将目标页面调入内存,将其唤醒,放回就绪队列
若内存有空闲,则直接为页面分配一个空闲块,并<font color="#F44336">改动对应页表项</font>
若内存无空闲,根据<font color="#F44336">置换算法换出一个页面</font>,若其被修改过,则写回外存,<br>若未被修改,无需写回。然后将该块分配给待调入页面<br>
一条指令可能产生多次缺页中断<br>
只有写指令写入对应页面时才需要修改页表项的修改位,以减少访存<br>修改也只需修改TLB中的快表项,并在删除快表项时才写回内存。<br>
换入换出速度极慢,大量等待IO,换入换出越多,性能越差
调入内存后,需要修改慢表,并将对应项复制到TLB
地址变换机构
首先检查页号是否越界
快表是否命中
命中,直接访问
未命中,是否在内存中
在,直接访问
不在内存中,调入内存
页面置换算法<br>追求低缺页率<br>
最佳置换算法OPT
由于无法预测未来访问的页面,不可实现
理论性能最佳
先进先出FIFO
不考虑局部性原理,即使最先调入Cache访问也可能最频繁
实现简单
刚被换出的块很快又被换入,频繁换出换入导致抖动
Belady异常
增加物理内存大小,缺页次数不减反增的现象
只有FIFO会产生此异常
最近最久未使用LRU
每次淘汰最近最久未被访问的页面
考虑了局部性原理,命中率高,但是需要专用硬件支持
<font color="#F44336">若频繁访问的主存块数量大于Cache块数则还是存在抖动</font>
手动计算
自替换处逆向寻找当前内存块,出现最晚的页面被替换<br>
时钟置换算法CLOCK<br>最近未使用NRU<br>
性能和开销相对均衡
实现<br>
为页面设置一个访问位,通过链接指针将页面链接成环形
访问某页时,设访问位为1
淘汰某页时,访问位为0则换出,若是1,<br>则置为0,且暂不换出,检查下一页面。<br>
由于内存被组织为环形,第二轮扫描必有0,因此淘汰一个页面最多只需两轮扫描
改进时钟置换算法<br>淘汰最多扫描四轮<br>
优先淘汰未修改过的页面(修改位为0)
第一轮尝试找到未访问,未修改(0,0)<br>本轮不修改任何标志位<br>
第二轮尝试找到未访问,修改过(0,1)<br>本轮只修改访问标志位<br>
修改使(1,0)变回(0,0)
第三轮尝试找到未访问,未修改(0,0)<br>本轮不修改任何标志位<br>
第二轮尝试找到未访问,修改过(0,1)<br>
必然存在
页面分配策略
驻留集
请求分页存储管理中,给进程分配的物理块集合
驻留集过小,缺页频繁
驻留集过大,并发度下降,资源利用率降低
页面分配、置换策略<br>
固定分配局部置换
驻留集大小固定,且页面置换只能是自己的页面<br>
固定分配不可能全局置换
可变分配全局置换
驻留集大小可变,且页面置换可以来自<br>其他位置甚至其他进程<br>
换入时若无空闲块,选择一个未锁定的页面换出内存<br>
缺页时就进程多分配了一个物理块
OS锁定部分重要的不可换出的页面,如OS的数据<br>
可变分配局部置换
缺页率高,增加物理块
缺页率降低,减少物理块
调入页面的时机
预调页策略
一次调入若干相邻的页面<br>
一般只用于进程首次调入时,由程序员指出需要调入<br>
请求调页
IO开销大,缺页时调入
从何处调入页面<br>
有足够的对换区空间
从对换区调入
无足够的对换区空间
凡不会被修改的,从文件区调入(不会再写回)
凡可能被修改的,写回对换区
UNIX方式
未使用过的页面,从文件区调入
换出时写回对换区,以后再从对换区调入<br>
抖动
频繁的页面调度称为抖动(换入后马上换出,换出后马上换入)
物理块不足
工作集
某段时间间隔内,进程实际访问的页面的集合
OS根据窗口尺寸计算工作集
工作集越小,局部性越好
OS可以监控进程的运行,统计出进程的工作集大小,从而指导驻留集的大小
驻留集一般不小于工作集
基本概念
内存
缓和外存和CPU的速度矛盾
存放待运行的程序
地址
用于标记程序存放的位置<br>
常见的数量单位
B
K-<span class="equation-text" data-index="0" data-equation="2^{10}" contenteditable="false"><span></span><span></span></span>,M-2<span class="equation-text" data-index="1" data-equation="^{20}" contenteditable="false"><span></span><span></span></span>,G-2<span class="equation-text" data-index="2" data-equation="^{30}" contenteditable="false"><span></span><span></span></span>
进程运行的基本原理
指令工作原理
操作数OP<br>
操作数
地址<br>
寻址方式
地址
逻辑地址
程序生成时,指令指明的是逻辑地址<br>即相对于起始地址的地址(相对地址)<br>
物理地址
执行过程中实际访问的地址(绝对地址)<br>
从代码到程序
编译
将源代码编译为汇编代码
汇编
将汇编代码转换为机器指令
链接
将目标文件生成装入模块,此时才有逻辑地址
装入
将装入模块装入内存,此时才形成物理地址
三种装入策略
绝对装入
如果编译器知道程序会装入的内存地址<br>编译器可以直接产生绝对的目标代码<br>
一般由编译器完成,单道程序阶段,还没有OS的概念
可重定位装入<br>(静态重定位)<br>
<font color="#F44336">装入内存时</font>,由OS根据实际装入地址,<br>将所有逻辑地址重定位为物理地址<br>
装入内存时,必须<font color="#F44336">一次性</font>分配要求的空间<br>不能分配时,不能装入该作业<br>
适用于早期多道批处理系统
动态运行时装入<br>(动态重定位)<br>
运行程序过程中,当需要访问地址时,<br>将逻辑地址和起始地址相加得到物理地址<br>
需要一个重定位寄存器,存放装入模块存放的起始位置
允许程序在内存中移动
可将程序离散地分配到存储区中
可以向用户提供比存储空间大得多的地址空间
三种链接策略
静态链接
运行前将目标模块和所需库函数<br>连接成完整可执行文件<br>
装入时动态链接
在装入内存时链接所有目标模块和所需库函数
运行时动态链接
运行时根据需要将模块调入内存并链接
内存空间分配与回收
任务
记录内存的分配情况
确定程序的装入位置
回收结束进程的资源
连续分配管理方式
单一连续分配<br>MS-DOS<br>
内存分为系统区和用户区
进程独占用户区<br>
不支持多道程序
不存在外部碎片,但是有内部碎片
分配了但没用到称为内部碎片
固定分区分配
用户区被分为了固定大小的分区
分区大小可以相等也可以不等
需要建立分区说明表
表项包含编号、大小、<br>起始地址、分配状态<br>
实现简单、无外部碎片,有内部碎片
动态分区分配<br>可变分区分配<br>
分区大小正好适合进程需要,动态建立分区
数据结构
空闲分区表
表项:分区号、大小、起始地址、状态
空闲分区链
结点结构:指向前后结点的指针<br>、分区大小、起始地址<br>
空闲分区分配算法
首次适应<br>FirstFit<br>
每次从低地址开始查找,找到第一个满足需求的空闲分区
低地址部分产生很多碎片
无需排序
临近适应<br>NextFit<br>
在FirstFit的基础上,可将空闲分区排成循环链表
从<font color="#F44336">上次查找结束的位置开始</font>查找分区
可能导致本来可以利用的低地址小分区浪费,过早用完连续大空间
无需排序
最佳适应<br>BestFit<br>
将空闲分区按递增排列,找到的第一个满足需求的空闲分区<br>
每次分配,若产生碎片,需重新排序,有一定开销
大量产生碎片
最坏适应<br>WorstFit<br>
将空闲分区按递减排列,找到的第一个满足需求的空闲分区
每次分配,若产生碎片,需重新排序,有一定开销
对大进程不友好<br>
有外部碎片:内存中空闲分区因太小而无法利用
可以通过“紧凑技术”(挪一下)解决
紧凑时需要修改PCB中的起始地址
分区的分配策略和回收策略如何
回收时,注意空闲分区的合并<br>不允许出现相邻的空闲分区<br>
非连续分配管理方式<br>(离散分配管理方式)<br>
基本分页存储管理
背景
块式存储要求数据必须存放在连续的物理块中,这导致了主存利用率的下降
物理块有别称
<font color="#F44336">页框</font>
页帧
物理页面
将<font color="#F44336">进程</font>分为与物理块<font color="#F44336">等大</font>的“页面”(页),并进行编号,允许离散地存储到主存中<br>页对用户不可见。<br>
页表(慢表)<br>
页表项
记录逻辑页号和主存块号的对应关系
逻辑页号:主存块号
由于页表项连续存放,页表项的逻辑页号不占字节
页表基址X,页号为i的页表项地址为X+size*i<br>
主存块号不是起始地址,addr=sizePage*块号<br>
通常以页表基址、页表长度形式存储在PCB中
页表项被访问时...<br>相当于一次访存(慢)<br>
把该项对应的块放入Cache
把该项放入快表
快表TLB<br>SRAM<br>相联存储器<br>专用硬件
快表项<br>
逻辑页号:主存块号
查询成功(命中)...
直接得到主存块号<br>
只需最终访存一次
与Cache的区别
Cache存<font color="#F44336">主存块</font>的副本
快表存<font color="#F44336">页表项</font>的副本(很小)
替换<br>
两级页表<br>页表的页表<br>(页目录表)<br>
单级页表的问题
页表很大,占据很多连续页框
基于局部性原理,没必要所有页表都常驻内存<br>
虚拟存储技术
页表项增加一项是否调入内存
缺页中断
将页表拆分为页面,为页面再建立一层页表<br>
又称外层页表、顶级页表
地址结构可以进一步拆分为:一级页号、二级页号、页内地址
多级页表的大小均不能超过一个页面
n级页表访存次数为n+1(不使用TLB)
地址转换
A的物理地址=页面P页号*页面大小+页内偏移量W<br>
页号=<span class="equation-text" data-index="0" data-equation="\lfloor\frac{逻辑地址}{页面大小}\rfloor" contenteditable="false"><span></span><span></span></span>
若页面大小为2的n次幂,则地址末n位<br>为页内地址(偏移量),其余部分为页号<br>
基本分段存储管理
根据自身逻辑将程序划分为若干(不等大的)段,按段名区分<br>段名对用户可见,需要显式地给出段名,是二维的编址方式<br>
每段自0编址
允许
LOAD 1,[D]|<A>;
[D]→段号;<A>→段内地址
STORE 1,[X]|<B>;
段内地址长度决定段大小,段号长度决定段数<br>
段表
段表项<br>对应一个段
段号
默认存在,不占空间
段长
各有不同,必须记录<br>
段基址
地址转换
A的物理地址=逻辑段的段基址+段内地址<br>
单级页表只需要两次访存
<font color="#F44336">一定需要检查地址是否越界</font>
段内地址超出段长则产生越界中断
通过将不同段表的段表项设为相同基址,可以简单地共享代码段
段页式存储管理
背景:分段/分页的优缺点
分页
空间利用率高,无外部碎片,少量页内碎片
不便于按照逻辑模块实现信息共享、保护
分段
段长若过长,为其分配连续空间非常不便<br>产生外部碎片<br>
信息共享,保护实现简单
分段和分页的结合
先分段,再对段进行分页
地址结构:段号+页号+页内偏移量
段表/页表
段表项:段号(隐含)、页表长度、页表基址
一个进程可能多个页表<br>
页表项:页号(隐含)、块号
用户只需要提供段号和段内地址,页号和页偏移量是自动计算的
地址转换
A的物理地址=逻辑段基址+页地址+页内偏移量
段号和页号都要检查是否越界<br>
不使用快表,需要访存3次<br>
使用快表,只需访存一次
0 条评论
下一页