首页 > 技术文章 > 分页存储和分段存储

katachi 2019-04-28 22:53 原文

预备知识:

以下讨论默认运算优先级为算数优先级,若未特殊说明,"="表示相等关系.

1.二进制乘数词头国际单位制词头

以M(兆)为例:

图一

图二

图三

 

图一为国际单位制兆以及相应词头间转换关系,结合图二可以看出,两种词头表示的"兆"之间有明显区别,兆在国际单位制中大于二进制中.其它词头可以相类比.

我们从店家购买U盘内存条等存储大小都是按照国际单位制词头标识,但是计算机大多是按照二进制乘数词头标识.因而有买32G U盘,插入电脑一看总容量只有29.8GB.

1999年,国际电工委员会(IEC)拟定了一种新标准,简单说就是在二进制词头的英文字符后加一个"i",取自binary.按这个标准,上面的U盘应该标注为29.8GiB.但是除了在相关行业,市场上大多还是沿用的SI的词头.

我们不关心这个,只记住下文采用IEC标准,前面这些都只是为了理解下面的知识. 

2.按字节编址和按字编址

假设某计算机为64位(bit),并假设一块内存大小2GiB,那么所谓的自然字长就是64bit.这个条件只在按字编址的时候用到.

按字节编址就是说,一个地址对应一个字节的存储空间.那么这2GiB编址或者寻址的范围怎么算?一种思路是把所有词头都化为bit(缩写为b).

2GiB=2^34bit 按字节(Byte缩写为B)那么 1B=8=2^3b 所以 2^34 / 2^3 = 2^31 ,也就是说需要31条地址线,寻址范围为 0~(2^31-1) .

按字编址,由于字长为64b,即 2^6b.那么 2^34 / 2^6 = 2^28 ,需要28条地址线,寻址范围 0~(2^28-1).

可以看出按字编址需要的地址线更少.我们关心的是大多数计算机内存都是按字节编址,或者说下面说的页表段表是按照字节编址.

即一个地址对应一个字节!

3.逻辑地址空间和物理地址空间

目标程序中使用的是逻辑地址,总是从0开始编址.逻辑地址对应实际的地址就是物理地址,逻辑地址到物理地址之间有一个转换关系,具体见下文.

4.内部碎片外部碎片

内部碎片指以分配给进程的内存,但是部分未能被利用到,外部碎片指某种存储管理方法下无法被分配的片段.


 

一.基本分页存储管理

1.页面和页框(物理块)

分页存储管理将逻辑地址空间分为相等大小的若干页,从0开始编号.相应地,把物理地址空间也分为若干个块,也是从0开始编号.但是不一定或者说一般两者的编号不是直接对应相等的.实际可能是0页对应3块...

我们的讨论基于页面大小等于块大小,即页内位移等于块内位移.这样两者大小对应,并且可以简化模型.

页面大小选取关乎内存效率,小可以减少内部碎片但进程会占用更多页面进而花更多时间在换页上,大可以减少页面长度但又会导致页内碎片增大.我们的讨论页面大小为4KiB.

2.地址结构

假设系统为32b,那么

低12b表示位移量W,因为是按字节编址,同时也说明页面大小为2^12B=4KiB.这个位移量就是页内偏移也等于块内偏移.

高20b代表也号,最大有2^20=1M页.一个进程中的逻辑地址按如上方法描述.

假设某逻辑地址为A,那么P=A/L,'/'为取整,'L'为页面大小,这里为4KiB.W=A%L.

3.页表

前面提到的逻辑地址到物理地址转换中,页表就是描述(指定)两者对应关系.

页表由若干连续页表项构成,本身需要放进内存里面,占用内存空间.

一个页表项由页号及其对应的块号构成,由于一个页表占用的是连续空间,所以页号本身不需要存储,只需要页表的起始地址和根据逻辑地址算出来的页内位移就可以找到所有物理块.

页表寄存器(PageTableRegister)被设计来存储页表起始地址和页表长度(页表大小).页表长度用于判断非法访问中断的条件.

 4.地址转换

1.根据逻辑地址计算出页号,页号同页面大小比较,等于或大于即产生中断,否则进入下一步.

2.页表(起)始地址+页号*页表项长度,得到该表项在页表中的位置,访问它即可得到块号(物理地址).(第一次内存访问)

3.块号+页内位移,得到欲访问数据的最终地址,访问它即可得到数据.(第二次内存访问)

这个页表项长度尤为注意!什么是页表项长度(也称页表项大小)?

前面说了,页表本身是要放进内存里的,且页表占用的是一个连续空间.那么相邻页表项之间差多少地址?我也不知道!

这得看具体内存管理怎么设计的,一个页表项用来存储块号,这个块号最大有多大,需要占用多少个二进制位来存储是需要看某具体机器的.

而且一页表项还会存储某些控制位,如读写控制.只需一个bit,我令它为0时表示可以读写,1时只能读.这样可以提供一种保护机制.看教科书或者参考书说的4B其实也是假设的,不要理解为32b的计算机,页表项大小就一定是4B=32b!

 

注意区分(ctrl+f):页面大小,页表大小,页表长度,页表项大小,页表项长度.有的是相同有的是包含.只说没提到的,页表大小=页表长度*页表项大小.

二.基本分段存储管理

1.地址结构

由于页表大小太大(相对的),实际可能不会有那么一块大的且连续的内存来存储页表.(分段存储的其他诸多优点自行翻书).人们又设计了另一种存储方法.

那么

 高低个16b.

可以看到和分页地址很像,确实有很多特性类似,但是实际分段是二维而分页是一维.

因为分页只是计算机自动完成将进程用到的内存(逻辑的)分成若干连续页,某个逻辑地址对应的物理地址是一维对应,本身页表项也只存了块号.

而分段,段表项存的是某段段长和该段始址.分段每一段长度没规定一定要相等!所以有种二维特性.

2.段表

地址空间被分为若干段,每段编址都从0开始,不同段通过段号确定.

 既然不同段都是从0开始编址,那我怎么知道0到底是哪段?

这里的编址说的是编逻辑地址中的低16b,即段内地址.段号是装入时分别分配的.

也就是说不会有两个逻辑地址相等,最多只是低16b相等,但是32b是不等的.

3.地址变换

1.逻辑地址>>16得到段号,段号同段表长度比较,等于或大于即产生中断,否则进入下一步.

2.段表(起)始地址+段号*段表项长度,得到该表项在段表中的位置,访问它即可得到段长和段始址.(第一次内存访问)

3.检查段内地址是否超过段长,等于或大于产生中断,否则进入下一步.

4.该段始址+段内位移,得到欲访问数据的最终地址,访问它即可得到数据.(第二次内存访问)

我们的所有讨论都基于这个段表项大小.

19版天勤OS笔记说

汤晓丹4版OS指出,

页表段表在内存中是一样的,都要一块连续而完整的空间.只是由于一段大小往往大于一页大小,因而段表小于页表.

但是对于页号或者段号,他们的分布是类似的,因而获取某个段表项应该和页表项应该是一样的.

看书时一直想不明白,天勤这个应该是写错了.只是练习题中,往往段号块号直接给出,你直接去看表就定位到段表项了,不会算这一步.

 


 

REF:

https://zh.wikipedia.org/wiki/%E5%9B%BD%E9%99%85%E5%8D%95%E4%BD%8D%E5%88%B6%E8%AF%8D%E5%A4%B4

https://zh.wikipedia.org/wiki/%E4%BA%8C%E8%BF%9B%E5%88%B6%E4%B9%98%E6%95%B0%E8%AF%8D%E5%A4%B4

https://blog.csdn.net/qq_26222859/article/details/50558253

https://blog.csdn.net/qq_28602957/article/details/53637103

https://blog.csdn.net/misayaaaaa/article/details/77622207

推荐阅读