操作系统-内存管理3(非连续内存分配)

一、基本概念

页帧:
连续内存分配存在内部碎片或者外部碎片,可以考虑将物理内存分为一个个大小固定的分区,叫做页帧(或者页框)。页帧的编号叫做页帧号(或者页框号,内存块号),页帧号从0开始。

页面:
将用户进程的地址空间也分为和页帧大小相同的一个个区域,称为页或者页面。最后一个页面可能不足页帧大小。将每一个页面分配到不同的页帧中,就是非连续分配。

页表:
页表用来保存逻辑页面和页帧的对应关系,页表的每一项叫做叶表项,叶表项由页号和块号(页帧号)组成。比如1号页面保存在6号页帧中,2号页面好存在8号页帧中。页面存在页帧上时离散的,但是在页帧内是连续的。
所以如果知道一个逻辑地址W,如何计算对应的物理内存地址?
1)计算页号 = W / 页面大小
2)偏移量 = W % 页面大小
3)通过页表找到该页号对应的页帧号P
4)实际地址 = 页帧号P * 页帧大小 + 偏移量

如下图所示页表结构
在这里插入图片描述

二、逻辑地址到物理地址的转换

2.1 逻辑地址的结构
分为页内偏移量和页号
在这里插入图片描述
2.2 地址转换过程
设页面大小为L,逻辑地址A到物理地址E的变化
1)根据逻辑地址A计算出页号P=A/L、页内偏移量W=A%L
2)比较页号P和页表长度M,如P>=M,则产生越界中断,否则继续执行(注意,页号P的起始值是0,而页表长度M至少是1,所以P==M也会越界)
3)页表中页号P对应的页表项地址=页表起始地址F + 页号P * 页表项长度取出该页表项内容b即为内存块号(页表项长度是页表中每一项的占的存储空间大小,页表长度表示该页表有几项)
4)计算 E = b * L + W

注:在操作系统中页面大小是已知的,只需知道逻辑地址计算实际地址。应为页号和偏移量可以根据逻辑地址算出,内存块号可以根据页号和页表计算得出。

计算如下图所示:
在这里插入图片描述

2.3 页表项的结构
在上述计算页表项地址时,我们使用到了页表项长度。页表也是存在内存中的,只有找到页面所对应的页表项在内存中的地址,才可以取出存在该内存地址上的内存块号。
页表也是存储在内存块中,假如一块内存块(页帧)的大小是2^12 = 4096B=4K大小,对于32位操作系统来说,一个进程最多有2 ^20 - 1个页面,理论上可以使用3个字节(一个字节8位,3个字节24位)来表示所有页面。4096/3有余数,计算不方便,所以实际上时用4个字节来表示页表项大小,使得一页恰好可以存储整数个页表项。
在这里插入图片描述

总结:
在这里插入图片描述
2.4 具有快表的地址变换机构

局部性原理
时间局部性:如果执行了程序中的某个指令,那么不久之后很有可能会再次执行该指令;如果访问了某个数据,那么不久之后很有可能会再次访问该数据。
空间局部性:一旦访问了某个存储单元,在不久之后,其附近的存储单元也有可能被再次访问。

通过上面的转换过程可以看到,CPU先要访问一次页表,找到实际物理地址,再访问一次实际物理地址去执行指令或者提取数据。需要两次访存。根据局部性原理,很有可能多次查到的是一个页表项。既然如此,能否利用此原理减少页表的访问。

可以通过块表(又叫联想寄存器TLB),是一种访问速度比内存快很多的高速缓冲存储器。当用来存储页表的某些项,可以加快地址的变换过程。与此对应,内存中的页表称为慢表。

增加快表后访问流程:
与之前的地址转换基本一会,只不过在查询页表之前会先查询快表,如果查到直接计算出物理地址,只需要一次访存。如果查不到,需要去页表中查询对应的内存块号,同时将页表项更新到快表中。(其实快表就是缓存,保存红页表的一部分数据)
在这里插入图片描述

三、两级页表

单级页表存在的问题
对于一个32位系统,如果一个页面大小是4K(2^12B),则一个进程最多有2 ^20个页面,也就是一个页表最多有2 ^20(1048575)个页表项。如果一个页表项的大小是4个字节,则一个内存块保存4K/4B=2 ^10个页表项,最多需要2 ^10个内存块来保存一个页表。
1)页表必须连续存放,因此当页表很大时,需要占用很多的连续内存块
2)没有必要让整个页表常驻内存,应为一段时间只可能需要访问某几个特定页面

解决上述两个问题的思路是将大的页表再次分组,使得一个内存块(页帧)恰好能保存一个分组(2 ^10个页表项),再将各组离散的放到内存块中。另外要为这些离散分配再建立一张表,称为页目录表(或者叫外层页表、顶层页表)

二级页表原理图:
在这里插入图片描述
二级页表的寻址过程
大致过程和以及页表一致,只不过 比一级页表多了一次查找表的过程。
1)首先按照地址结构,将逻辑地址划分成一级页号、二级页号和页内偏移量(按照二进制,前十位一级页号,中间十位二级页号,最后12位页内偏移量)
2)从PCB中读出页目录表的起始地址,再根据一级页号查找下一级页表在内存中对应的地址,读出内存中对应的下级页表内容
3)在根据二级页表号,在下级页表中找到最终的内存块号
3)结合偏移量计算出实际地址。

二级页表总结
在这里插入图片描述

四、分段分配

程序按照自身的逻辑划分为若干个段,每个段的长度不相等(和分页的最大区别),每个段都是从0 开始编址。

4.1 段表
程序分多个段,离散的装入内存,为了保证程序能正常运行,必须能从物理段中找到各个逻辑段的存放位置。为此需要建立一张段映射表,叫做段表。

段表包括:段号,段长(每一段的长度)和段基址(每一段的物理起始地址)

段表结构如下图
在这里插入图片描述
4.2 分段寻址过程:
与分页寻址基本一致,但是计算物理地址E之前需要校验段内地址是否越界。应为每段的段长是不一样的。

1)根据逻辑地址得到段号S和段内偏移量W
2)判断段号是否越界,S>=M,则越界
3)根据段寄存器的段表始址F和段号S,通过公式F+S*段表项长度,计算出段表项在内存的地址
4)检查段内偏移量是否超过段长,若W>=C,则超过
5)根据E=段基址b+段内偏移量W,得到物理地址

在这里插入图片描述
4.3 分段和分页比较
1)页是信息的物理单位,分页是位于提高内存利用率,是系统行为,对用户是不可见的。段是信息的逻辑单位,目的是为了满足用户需求,一个段通常包含程序的一个逻辑模块,分段对用户是可见 的,编程时用户需要显示地给出段名。
2)页面的大小是固定的,有操作系统决定;段的大小不固定,有用户编写的程序决定。
3)分页的用户进程地址空间是一维的,程序员只需要一个变量表示即可;分段的用户进程地址空间是二维的,程序员在表示一个地址时,既要给出段名也要给出段内地址。
4)分段更容易实信息的共享和保护。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值