操作系统原理 : 非连续的内存分配,分段,页表

非连续的内存分配通常,分段和分页两种方式

由于连续的内存分配方式存在碎片问题。非连续的内存分配就可以充分利用内存碎片,主要存在的问题就是开销,如果碎片多寻址效率会比较慢。

目录

一、分段

二、分页机制

三、页表

四、二级页表和多级页表

五、反向页表


一、分段

1)分段地址空间

数据是由段存储,根据应用执行的特点可以将段进行分类:例如文件头,代码段、数据段、符号表、堆、栈等。采用分段管理方式,就是将段进行分类区分管理。

2)分段寻址方法

分段寻址方法即根据逻辑地址空间映射到物理地址空间。将单位逻辑地址分成两部分,第一部分是段号,第二部分是段内的偏移。 段号可在段表里找到物理内存中对应的起始地址,然后在这起始地址上加上段偏移量,得到程序的内存空间起始位置。在段表里除了物理内存对应的起始地址还包含该段的最大长度限制信息,如果访问越界则访问非法(段错误异常)

二、分页机制

1)分页地址空间

 分页和分段一样,将单位逻辑地址分成两部分,也需要有一个页号和页偏移。区别在于一个页的大小不可变,是固定的。它的大小是2的幂。例如512,1024,2048.。。。。 页号偏移的大小和页帧偏移的大小是一致的。

页帧是一种物理内存的组织和布局方式,页是逻辑地址的寻址方式。页帧也有页帧号和镇内偏移,物理地址也就可以得出来。例如在一个16bit的地址空间其中9bit是页帧偏移,剩下7bit表示页帧号当物理地址二元组表示是(3,6)对应的地址是1542

(逻辑)页映射到(物理)页帧,页是连续的虚拟内存而页帧是非连续的虚拟内存,由助于减小内存碎片的产生,并不是所有的页都有对应的帧,逻辑地址要步物理内存地址来的多,有些逻辑地址的页号并不能在页表中找到对应的帧号。通常只需要从逻辑地址的页号在页表上查询到帧号,得到帧号。又因为页号偏移的大小和页帧偏移的大小也是一致。从而得到物理内存的空间。 

三、页表

页表数据结构,就相当于一个大数组,页号就相当于数组的索引,这个大数组里面存放的就是帧号。通过逻辑页号算出索引值从而得到帧号,外加上逻辑偏移地址就可以找到物理地址。其中标志位中resident表示该页号是否存在,如果是0则表示没有可映射的物理内存页号。页表的建立是由操作系统来完成的,页表也是需要占用内存空间的。

例如:逻辑地址空间有16bit ,意味者2^16 B = 64K的逻辑地址空间,但是物理空间只有32K,页大小1k。逻辑页有由元式表示 (4,0),说明页号是4,偏移量是  0,经过PTBR运算得到在页表中flags=100 , resident位是0,则表示该页号没有可对应的物理内存,得到一个内存访问异常。

同理逻辑页由二元式表示 (3,1023),说明页号是3,偏移量是 1023,经过PTBR运算得到在页表中flags=011 ,对应的帧号frameNum = 00100=4, 所以对应的物理内存是  (4,1023),由于页帧号5bit,页偏移量是10bit 所以对应的物理内存值是  2^10 * 4  + 1023   =5199

页表也是需要占用内存空间的。假如64位的机器,每页1024字节,用一个页表来完成逻辑地址到物理地址的映射,则需要 2^64 / 1024  =2^54 个映射关系,意味着如果想要尽可能映射逻辑地址,可能页表会放的跟大。其次一台计算机上可能会有多个应用程序在执行,每个应用程序都要求自己的一套页表,所以一般的计算机很难完成用单个页表的完成映射。其次要考虑的是时间开销问题,因为页表也是存储在内存中,页表访问方式相当于至少访问两次物理内存?对于时间上的开销其中一种方式就是CPU上的缓存机制,还有一种方式就是间接访问的方式。

CPU的块表(TLB),把经常访问的页号存到TLB,如果命中则直接在CPU中取,如果没命中再到内存页表中取,取完后更新块表。注意这个取TLB的过程是由CPU完成,而TLB未命中后的操作由操作系统完成。

四、二级页表和多级页表

一般的计算机很难完成用单个页表的完成映射,可以用多级页表完成。即只有最后一级的页表项存的是页帧,而第一级开始当作页表的索引,页表项存的是下级页表的起始地址。当然resident标志在索引层页表是可以省略的。虽然页表增多,但是到最后的偏移量是不变的。多级页表在相同的内存空间下增加了多层级的访问映射,层级虽多,但是页表总大小要比单一页表大小来的少得多,当然访问时间的开销就会变得大。

五、反向页表

有没有一种方法让,页表的空间大小和逻辑地址页号没有直接的关系,尽量和物理地址空间的页号建立映射关系,这么做的好处就是占用地址空间相对较少。那么这种方案需要考虑的问题就是CPU获取逻辑地址时怎么样去取物理地址?

可以利用当前程序运行的进程号Pid 和CPU获取到的页表号通过一个简单的hash函数得到一个页帧号。组织结构没变、当然hash函数最好通过硬件计算(PTBR页表基址寄存器)来实现,此方法需要考虑的时键值冲突的问题。

猜你喜欢

转载自blog.csdn.net/superSmart_Dong/article/details/115840418