目录
一、为什么要有段式管理?
二、段式管理的实现原理
1、段式虚拟空间
2、段式管理的内存分配与释放
3、段式管理的地址变换
(1)段表
(2)动态地址变换
4、段的共享与保护
(1)共享
(2)保护
四、段式管理的优缺点
五、段页式管理
1、为什么会有段页式管理?
2、段页式管理的实现原理
(1)虚拟地址的构成
(2)段表和页表
3、动态地址变换
一、为什么要有段式管理?
我们的程序在很多时候是需要共享的
例如我们写的头文件的代码就需要被其他文件共享
同时,一个开放文件的函数方法,也很可能要被其他文件调用
于是,这就提出了对程序和数据进行分享的要求
为了支持共享的需求,需要对内存采用特殊的管理方式
那么应该采取什么方式?
首先想到的是先前学到的分区式管理和页式管理
但是对这两种内存管理方式来说
很难实现程序和数据共享
为什么?
一、对分区式管理来说:
对于该种方法,内存分配的最小单位是一整个分区块
一整个进程的程序和数据都放在一个分区块中
共享只能对一整块进行共享,而不可能再进行分割
但是这是不现实的,不可能让某个进程的所有程序和数据都暴露
二、对页式管理来说:
内存分配的最小单位是页
似乎可以进行共享,例如把某几页共享出去
但是,也不现实
为什么
因为,一个完整的执行逻辑,可能程序和数据在不同页中
而且不同页的那个地方,也是不清楚的
因此,页式管理对程序和数据的共享也无法实现
综上,旧有的内存管理方式无法支持
如何?
只能寻求新的管理方式
于是,基于此,段页式管理应运而生
同时,段式管理的出发点,
就是以功能完整的逻辑段作为单位进行划分
二、段式管理的实现原理
1、段式虚拟空间
一个进程的虚拟空间为二维:段号s + 段内地址w
段号之间没有顺序管理(不同于页式的页号式有顺序的一维度结构)
段的长度不同,根据逻辑功能完整的程序和数据进行划分
例如:
一个进程的程序和数据被划分为:
程序段、子程序段、数据段和工作区
每个段是一个首地址为0的、连续的一维线性空间
根据需要,段的长度可以动态调整
对段式虚拟地址的访问包括两个部分:段名 + 段内地址
2、段式管理的内存分配与释放
以段为单位分配内存,每段是一个连续的内存区
同一进程所包含的各段之间不要求连续
进程申请段内存时,有两种情况:
(1)进程要调入某段,内存空闲区足够
(2)进程要调入某段,内存空闲区不够
对(1):够用
采用和分区式动态管理方法一样:
用申请表、可用表 / 自由链 进行管理
不同分区组织方式
对应不同的分配算法可用:最佳、最先、最坏算法
回收方法也一样,对回收段修改状态,加入可用表
对(2):不够用
此时就要对内存中某些块进行置换
置换哪些?
同样,可依照动态分区式管理方法:
FCFS算法、LRU算法(最近最久未用)等
一般来说,有时候需要调入的段比较大
可能需要置换出不止一个段
对于释放,参考分区式管理的释放
注意:任何一个段的的段长都不可以超过内存可用区长度
3、段式管理的地址变换
段式虚拟空间的机制是部分程序和数据在内存中
大部分程序和数据保存在外存中
因此,在进程执行时,如果待执行的段不再在内存
此时,中断进程,调入相关段
可是,CPU如何知道某个段不在内存中呢?
很简单,对每个段是否在内存中设置一个状态即可
可见,对段的调入和调出内存是需要额外的数据结构支持的
例如段表
(1)段表
逻辑格式如图所示:
始址:该段在内存 / 外存的实际物理地址
长度:该段的长度
存取方式:对该段进行保护,只有访问的控制状态字和该字段一致才可访问
内外:指明该段存在内存还是外存中
访问位:为置换算法设置,例如淘汰没有被访问 / 访问次数最少的段
段表有一个段表寄存器
段表放在哪里?
一般放在内存一个固定的区域
(2)动态地址变换
CPU执行进程的全部访问过程:
当进程开始执行时:
第一步、把段表开始地址放入段表地址寄存器
第二步、访问段表地址寄存器,得知从哪里访问段表
第三步、根据虚地址中的段号,查段表
第四步、检查存取状态字,判断是否可以访问
第五步、如果可以访问,从段表中查到对应项目,拿出该段的内存起始地址
和段内相对地址w相加,得到实际内存地址
某段内存地址 = 该段内存始址 + 段内相对地址
段式地址变换需要对内存访问两次:
第一次,访问段表计算程序 / 数据物理地址
第二次,根据计算得到的地址,去实际访问数据
4、段的共享与保护
(1)共享
什么叫做共享?
其实就是我们写代码是的代码复用
例如有一个 add()函数
很多文件都使用到这个函数
是不是每一个文件都写一个呢?
没必要,太浪费
而是写一份,然后共享即可
节省空间
那么段式管理方法如何实现共享?
进程A想用进程B的C段时
直接在进程A的段表中填入C段的相关信息填入进程A的段表即可
并赋予合适的权限即可
共享访问过程中的一些问题
第一,修改数据问题
进程A共享了进程B的C段
可以,但是你不能修改C段的数据
否则进程B就出错了
第二、共享段调出问题
当进程调入段而内存不够用时
需要对某些段进行置换
很明显,对正在共享的段不应该被置换
因此,需要对段表中再加一个共享位
以区分是否被共享
(2)保护
存取控制方式 和 地址越界保护
存取控制方式,
就是上文所说的对段加上一个存取控制字
当某进程要访问该段时,应该检查控制字是否一致
不一致则拒绝
地址越界保护,
段的访问,是段号s + 段内相对地址
于是可以对段内相对地址 和 段的长度进行比较
如果段内相对地址 大于 段长度
很明显,越界,中断
注意:
在支持段动态增长的系统是允许访问的
四、段式管理的优缺点
优点:
1、支持同意内外存的虚拟存储,且每段都是有意义的信息(功能逻辑完成)
2、段长可以动态增长
3、便于共享
4、支持动态链接
缺点:
1、需要更多硬件支持,成本高
2、段式管理采取和分区管理一样的空闲区管理模式,存在小碎片空间问题
3、段的长度收可用区大小的限制
4、淘汰算法需谨慎,否则导致抖动
五、段页式管理
1、为什么会有段页式管理?
段式管理有便于共享、支持动态增长和内存保护的优点
页式管理有消除外部碎片的的优点,提高内存利用率
而进行存储管理的目的,就是为了便于用户程序设计和提高内存利用率
于是,可不可以把段式和页式结合起来呢?
可以
但是,这会是的管理方式变得更加复杂
产生了更大的系统开销
因此,段页式管理一般应用于大型机
2、段页式管理的实现原理
(1)虚拟地址的构成
一个进程中,具有独立逻辑功能的程序和数据被划分为段,并有各自的段号s
对段号s内的程序和数据,则被分成多个大小固定的页
于是,段页式的虚拟地址由三部分组成:
段号 s + 段内相对地址w
w = 页号p + 页内相对地址d
内存被划分为若干大小相等的页面
于是,段的大小不再受内存可用区的限制
(2)段表和页表
页表属于段而不是进程
其逻辑结构如图所示:
3、动态地址变换
地址变换分三步:
第一、访问段表内存,得到页表地址
第二、根据页表地址,访问内存,得到数据地址
第三、根据数据地址,访问内存,得到数据
因此,段页式的访问需要3次,大大减少了CPU的速度
基于此,段页式管理更加需要高速联想寄存器支持,以提高访存速度
将最常用的段号、页号和对应内存页和其他控制项直接放在高速联想寄存器中
当进程要访问内存空间某一单元时
首先检索高速联想寄存器
如果有,则直接将高速联想寄存器的段号、页号和段内地址d相加,得到内存地址
直接取数据
关于存储保护、共享、缺页中断可参考段式管理和页式管理