文章目录
1、内存的基础知识
-
内存:用于存放数据的硬件
-
存储单元:内存存储的基本划分单位
-
按字节编址:每个存储单元的大小是一字节(1B)
-
按字编址:每个存储单元的大小是一个字(字的大小取决于字长)
-
物理地址(绝对地址):是当前数据在整个计算机内存中的绝对位置
-
逻辑地址(相对地址):是指当前数据在本进程之内的偏移量地址
1.1 程序的运行步骤
- 编辑源代码文件
- 编译:由源代码文件生成目标模块
- 链接:由目标模块生成装入模块,链接后形成完整的逻辑地址
- 装入:将装入模块装入内存,装入后形成物理地址
1.2 三种链接方式
- 静态链接:装入前链接成一个完整的装入模块
- 装入时动态链接:运行前边装入边链接
- 运行时动态链接:运行时需要的目标模块猜装入并链接
1.3 三种装入方式
- 绝对装入
- 可重定位装入
- 动态运行时装入
1.4 内存管理的内容
- 内存空间的分配与回收
- 内存空间的扩充
- 地址转化
- 存储保护
2、地址转换
操作系统负责实现逻辑地址到物理地址的转换,三种方式
- 绝对装入:编译时将逻辑地址转化为物理地址
- 可重定位装入(静态重定位):装入时将逻辑地址转换为物理地址
- 动态运行时装入(动态重定位):运行时将逻辑地址转换为物理地址,需设置重定位寄存器
3、存储保护
保证各进程在自己的内存空间内运行,不会越界访问
- 设置上下限寄存器
- 利用重定位寄存器、界地址寄存器进行判断
4、内存空间的分配与回收
- 连续分配管理方式
- 单一连续分配
- 固定分区分配
- 动态分区分配
- 非连续分配管理方式
- 基本分页存储管理
- 基本分段存储管理
- 段页式存储管理
4.1 连续分配管理方式
连续分配是指为用户进程分配的必须是一个连续的内存空间.
外部碎片:没有分配的内存过小,无法分配给进程
内部碎片:分配给进程的内存无法被全部利用
特点 | 外部碎片 | 内部碎片 | |
---|---|---|---|
单一连续分配 | 只支持单道程序,用户程序放在用户区 | 无 | 有 |
固定分区分配 | 支持多道程序,内存用户空间分为若干大小固定的分区 | 无 | 有 |
动态分区分配 | 支持多道程序,根据进程大小动态地建立分区 | 有 | 无 |
(1) 单一连续分配
将整个内存空间全部分配给一个用户区
无外部碎片但是有大量的内部碎片,并且只能用于单用户单道
存储器利用率极低
(2) 固定分区分配
系统将用户空间划分为若干固定大小的区,每一个进程占用一个区.
-
分区大小相等
- 缺乏灵活性
- 但是很适合控制多个相同对象
-
分区大小不相等
- 增加了灵活性
- 常在系统中根据作业的大小分配内存
无外部碎片
有大量的内部碎片
(3) 动态分区分配
不会预先划分内存分区,而是在进程装入内存时,根据进程的大小动态的建立分区
两种常用的数据结构:空闲分区表、空闲分区链
空闲分区表(链):记录了每一个未被分配的分区(由已分配分区划分而出)的相关信息
没有内部碎片,但是有外部碎片,可以通过紧凑技术解决外部碎片
回收内存分区时,要合并相邻空闲分区
4.2 动态分区分配算法
算法 | 思想 | 空闲分区排列顺序 | 优点 | 缺点 |
---|---|---|---|---|
首次适应 | 从头到尾找合适的分区 | 以地址递增次序排序 | 综合性能最好,开销小,回收后不需要对空闲分区重新排序 | |
最佳适应 | 优先使用更小的分区 | 以空间容量递增次序排列 | 会有更多的大分区被保留,更能满足大进程需求 | 会产生很多小碎片,算法开销大,回收分区后需要对空闲分区重新排序 |
最坏适应 | 优先使用更大的分区 | 以空间容量递减次序排列 | 可以减少难以利用的小碎片 | 大分区容易被用完,不利于大进程,算法开销大 |
临近适应 | 由首次适应演变,每次从上次查找结束的位置开始查找 | 以地址递增次序排序 | 不用每次都从低地址的小分区开始检索,开销小 | 会使高地址的大分区也被用完 |
4.3 基本分页存储管理
4.3.1 分页基础
(1)概念
把内存分为一个个相等的小分区,称为页框,再按照分区大小将用户进程分为若干小分区,成为页面。每一个页面都对应分配一个页框
各个页面不必连续存放,也不必按照先后顺序来,可以放到不相邻的各个页框中.
操作系统为每个进程建立一张页表,其中按顺序存储了进程中每一个页对应的页框号(内存中的映射)
(2)地址转换(无页表)
- 计算出逻辑地址对应的页号
- 找出对应页面在内存的存放位置
- 算出逻辑地址对应的页内偏移量
- 物理地址=页面起始地址+页面偏移量
(3)页号、页内偏移量的计算
1)人工计算
页号=逻辑地址/页面大小
页内偏移量=逻辑地址%页面大小
2)根据逻辑地址存储结构
分页存储管理的逻辑结构如下所示:
00000000000000000000 000000000001
31 … 12 | 11 … 0 |
---|---|
页号P | 页内偏移量W |
如果有K位表示“页内偏移量”,说明该系统中一个页面的大小使2的k次个内存单元
如果有M位表示“页号”,则说明该系统中,一个进程最多允许有2的M次个页面
(3)页表
操作系统位每个进程建立一张页表,用来确定进程的每个页面在内存中的存放位置
- 一个进程对应一张页表
- 进程的每一页对应一个页表项
- 每个页表项由“页号”和“块号”组成
- 页面记录页面和实际存放的内存块之间的对应关系
- 因为每个页表项长度相同,所以页号使“隐含”的
4.3.2 基本地址变换机构
- 根据逻辑地址算出页号、页内偏移量
- 页号的合法性检查
- 若页号合法,再根据页表起始地址、页号找到对应页表项
- 根据页表项中记录的内存块号、页内偏移量得到最后的物理地址
- 访问物理内存对应的内存单元
细节:
- 熟悉页内偏移量位数与页面大小的关系
- 页式管理中地址是一维的
- 实际应用中,通常使一个页框恰好能放入整数个页表项
- 为了方便,页表一般使放在连续的内存块中的
4.3.3 快表
快表,又称联想寄存器(TLB) ,是一种访问速度比内存快很多的高速缓冲存储器,用来存放当前访问的若干页表项,以加速地址变换的过程。与此对应,内存中的页表常称为慢表。
引入快表前后的地址变换机构
- 算页号、页内偏移量
- 检查页号合法性
- 查快表。若命中,即可知道页面存放的内存块号,可直接进行⑤;若未命中则进行④
- 查页表,找到页面存放的内存块号,并且将页表项复制到快表中
- 根据内存块号与页内偏移量得到物理地址
- 访问目标内存单元
如果快表命中则只需有一次访存
4.3.4 两级页表
两级页表的地址变换
- 按照地址结构将逻辑地址拆分成3部分
- 从PCB中读出页目录表始址,根据一级页号查页目录表,找到下一级页表在内存中的存放位置
- 根据二级页号查表,找到最终想访问的内存块号
- 结合页内偏移量得到物理地址
细节:
- 多级页表中,各级页表大小不能超过一个页面
- N级页表访问一个逻辑地址需要N+1次访存
4.4 基本分段存储管理
4.4.1 分段基础
(1)概念
分段就是按照一些逻辑上的意义将内存进行划分,这样一来,每个段的大小是不固定的,与分段类似
(2)段表
- 段表与页表类似,记录了逻辑段到实际存储地址的映射关系
- 每个段对应一个段表项,各段表项长度相同
- 段表项由段号(隐含)、段长、基址组成
4.4.2 地址变换
- 由逻辑地址得到段号、段内地址
- 段号与段表寄存器中的段长度比较,检查是否越界
- 由段表始址、段号找到对应段表项
- 根据段表 中记录的段长,检查段内地址是否越界
- 由段表中的"基址+段内地址"得到最终的物理地址
- 访问目标单元
4.4.3 分页与分段管理对比
- 分页对用户不可见,分段对用户可见
- 分页的地址空间是一维的,分段的地址空间是二维的
- 分段更容易实现信息的共享和保护(纯代码/可重入代码可以共享)
- 分页(单级页表)、分段访问-个逻辑地址都需要两次访存,分段存储中也可以引入快表机构
4.5 段页式管理方式
利用分段式管理来管理页表,然后通过分页式管理来管理页.这样使用段表将页进行逻辑上的划分,也能实现易于共享的需求了.
这里的段表存放的就不是基址了,而是页表长度和页表存放块号
4.5.1 段表、页表结合
每个段对应一个段表项。各段表项长度相同,由段号(隐含)、页表长度、页表存放地址组成
每个页对应一个页表项。各页表项长度相同,由页号(隐含)、页面存放的内存块号组成
4.5.2 地址变换
- 由逻辑地址得到段号、页号、页内偏移量
- 段号与段表寄存器中的段长度比较,检查是否越界
- 由段表始址、段号找到对应段表项
- 根据段表中记录的页表长度,检查页号是否越界
- 由段表中的页表地址、页号得到查询页表,找到相应页表项
- 由页面存放的内存块号、页内偏移量得到最终的物理地址
- 访问目标单元
5、内存空间的扩充
- 覆盖技术
- 交换技术
- 虚拟存储技术
5.1 覆盖技术
覆盖技术是指将程序分为多个段,使用的那一部分调入内存,不使用的部分在需要时才会调入内存.
常驻内存的段放在固定区中,调入后不在调出。不常住的段放在覆盖区,需要时调入,采取覆盖策略
程序员必须显式声明覆盖结构
5.2 交换技术
当内存空间紧张时,将内存中某些进程暂时调出外存,把外存中某些已经具备运行条件的进程调入内存(内存和磁盘中动态调度)
中级调度就是判断哪一些进程适应给被调入的,暂时换出外存等待的进程状态被称为挂起态.
对应于此,磁盘空间也被分为对换区和文件区.对换区追求文件换入换出速度,采用连续分配方式.文件区追求空间的利用率,采用离散分配方式
注:PCB会常驻内存,不会被换出外存
覆盖与交换的区别:覆盖是在一个进程中的,交换是对不同进程的
5.3 虚拟存储技术
程序不需全部装入即可运行,运行时根据需要动态调入数据,若内存不够,还需换出一些数据
5.3.1 局部性原理
- 时间局部性:现在访问的指令、数据在不久后很可能会被再次访问
- 空间局部性:现在访问的内存单元周围的内存空间,很可能在不久后会被访问
- 高速缓存技术:使用频繁的数据放到更高速的存储器中
5.3.2 特征
- 多次性:无需在作业运行时一次性全部装入内存,而是允许被分成多次调入内存。
- 对换性:无需在作业运行时-直常驻内存,而是允许在作业运行过程中,将作业换入、换出。
- 虚拟性:从逻辑.上扩充了内存的容量,使用户看到的内存容量,远大于实际的容量。
5.3.3 传统VS虚拟
虚拟内存技术,允许-一个作业分多次调入内存。如果采用连续分配方式,会不方便实现。因此,虚拟内存的实现需要建立在离散分配的内存管理方式基础上。.
传统的非连续分配存储管理 | 虚拟内存的实现 |
---|---|
基本分页存储管理 | 请求分页存储管理 |
基本分段存储管理 | 请求分段存储管理 |
基本段页式存储管理 | 请求段页式存储管理 |
区别:
- 请求调页功能:访问的信息不在内存时,由操作系统负责将所需信息从外存调入内存
- 页面置换功能:内存空间不够时,将内存中暂时用不到的信息换出到外存
5.3.4 请求分页存储管理
(1)页表的区别
在基本分页的基础上增加了几个表项
- 状态位:表示页面是否已在内存中
- 访问字段:记录最近被访问过几次,或记录上次访问的时间,供置换算法选择换出页面时参考
- 修改位:表示页面调入内存后是否被修改过,只有修改过的页面才需在置换时写回外存
- 外存地址:页面在外存中存放的位置
(2)缺页中断机构
- 找到页表项后检查页面是否已在内存,若没在内存,产生缺页中断
- 缺页中断处理中,需要将目标页面调入内存,有必要时还要换出页面
- 缺页中断属于内中断,属于内中断中的"故障",即可能被系统修复的异常
- 一条指令在执行过程中可能产生多次缺页中断
(3)地址变换的区别
- 找到页表项是需要检查页面是否在内存中
- 若页面不再内存中,需要请求调页
- 若内存空间不够,还需换出页面
- 页面调入内存后,需要修改相应页表项
5.3.5 页面置换算法
算法 | 算法规则 | 优缺点 |
---|---|---|
最佳置换算法(OPT) | 优先淘汰最长时间内不会被访问的页面 | 缺页率最小,性能最好;但无法实现 |
先进先出置换算法(FIFO) | 优先淘汰最先进入内存的页面 | 实现简单;但性能很差,可能出现Belady异常 |
最近最久未使用置换算法(LRU) | 优先淘汰最近最久没访问的页面 | 性能很好;但需要硬件支持,算法开销大但未考虑页面是否被修改过。 |
时钟置换算法(CLOCK) | 循环扫描各页面,第一轮淘汰访问位=0的,并将扫描过的页面访问,位改为1。若第一轮没选中,则进行第二轮扫描。 | 实现简单,算法开销小; |
改进的时钟置换算法 | 用(访问位,修改位)的来确定置换 | 算法开销较小,性能也不错 |
5.3.6 页面置换策略
驻留集:指请求分页存储管理中给进程分配的内存块的集合
工作集:在某段时间间隔里,进程实际访问页面的集合。驻留集大小一般不能小于工作集大小
抖动(颠簸)现象:页面频繁换入换出的现象。主要原因是分配给进程的物理块不够
(1)页面分配、置换策略
固定分配VS可变分配:区别在于进程运行期间驻留集大小是否可变
局部置换VS全局置换:区别在于发生缺页时是否只能从进程自己的页面中选择一个换出
- 固定分配局部置换:进程运行前就分配一定数量物理块,缺页时只能换出进程自己的某一页
- 可变分配全局置换:只要缺页就分配新物理块,可能来自空闲物理块,也可能需换出别的进程页面
- 可变分配局部置换:频繁缺页的进程,多分配一些物理块;缺页率很低的进程,回收一些物理块。直到缺页率合适
(2)何时调页
- 预调页策略:一般用于进程运行前
- 请求调页策略:进程运行时,发现缺页再调页
(3)何处调页
对换区一采用连续存储方式,速度更快
文件区一采用离散存储方式,速度更慢
- 对换区足够大:运行将数据从文件区复制到对换区,之后所有的页面调入、调出都是在内存与对换区之间进行
- 对换区不够大:不会修改的数据每次都从文件区调入;会修改的数据调出到对换区,需要时再从对换区调入