1 基本分页存储管理
连续分配:为用户进程分配的必须是一个连续的内存空间。
非连续分配:为用户进程分配的可以是一些分散的内存空间。
1.1 什么是分页存储
- 将内存空间分为一个个大小相等的分区(比如:每个分区
4KB
),每个分区就是一个“页框”(页框=页帧=内存块=物理块=物理页面)。每个页框有一个编号,即“页框号”(页框号=页帧号=内存块号=物理块号=物理页号),页框号从 0 开始 。
- 将进程的逻辑地址空间也分为与页框大小相等的一个个部分, 每个部分称为一个“页”或“页面” 。每个页面也有一个编号, 即“页号”,页号也是从 0 开始 。
- 操作系统以页框为单位为各个进程分配内存空间。进程的每个页面分别放入一个页框中。也就是说,进程的页面与内存的页框有一一对应的关系。 各个页面不必连续存放,可以放到不相邻的各个页框中。
(注意:进程的最后一个页面可能没有一个页框那么大。也就是说,分页存储有可能产生内部碎片,因此页框不能太大,否则可能产生过大的内部碎片造成浪费)
1.2 重要的数据结构——页表
为了能知道进程的每个页面在内存中存放的位置,操作系统要为每个进程建立一张页表。
- 一个进程对应一张页表
- 进程的每个页面对应一个页表项
- 每个页表项由“页号”和“块号”组成
- 页表记录进程页面和实际存放的内存块之间的映射关系
- 每个页表项的长度是相同的
核心问题:
- 每个页表项多大?占几个字节?
- 如何通过页表实现逻辑地址到物理地址的转换?
- 已知计算机中内存块的数量→页表项中块号至少占多少字节?
假设某系统物理内存大小为
4GB
,页面大小为4KB
,则每个页表项至少应该为多少字节?
- 内存块大小=页面大小=
4KB
=212 B4GB
的内存总共会被分为 232/212 =220个内存块- 内存块号的范围应该是0~ 220-1
- 内存块号至少要用
20bit
来表示 →至少要用3B
来表示块号(3*8=24bit
)
页表项连续存放,因此页号可以是隐含的,不占存储空间(类比数组)
引出问题:假设页表中的各页表项从内存地址为
X
的地方开始连续存放…
如何找到页号为i
的页表项?
i
号页表项的存放地址=X+3*I
因此,页表中的页号可以是隐含的,即页号不占用存储空间
假设某系统物理内存大小为4GB
,页面大小为4KB
,则每个页表项至少应该为多少字节?
- 内存块大小=页面大小=
4KB
=212 B4GB
的内存总共会被分为 232/212 =220个内存块- 内存块号的范围应该是0~ 220-1
- 内存块号至少要用
20bit
来表示 →至少要用3B
来表示块号(3*8=24bit
)- 由于页号是隐含的,因此每个页表项占
3B
,存储整个页表至少需要3*(n+1)B
- 如何实现地址的转换
进程在内存中连续存放时 , 操作系统是如何实现逻辑地址到物理地址的转换的?
过程如下:
思考:将进程地址空间分页之后 ,操作系统该如何实现逻辑地址到物理地址的转换 ?
特点:虽然进程的各个页面是离散存放的,但是页面内部是连续存放的
如果要访问逻辑地址A,则 :
- 确定逻辑地址A对应的“页号”P
- 找到P号页面在内存中的起始地址(需要查页表)
- 确定逻辑地址A的“页内偏移量”W
逻辑地址A对应的物理地址=P号页面在内存中的起始地址+页内偏移量W
子问题:如何确定一个逻辑地址对应的页号、页内偏移量?
Eg:在某计算机系统中,页面大小是
50B
。某进程逻辑地址空间大小为200B
,则逻辑地址110
对应的页号、页内偏移量是多少?
如何计算:
页号=逻辑地址/页面长度 (取除法的整数部分)
页内偏移量=逻辑地址%页面长度(取除法的余数部分)
本例中页号=110/50=2
页内偏移量=110%50=10
逻辑地址可以拆分为(页号,页内偏移量)
通过页号查询页表,可知页面在内存中的起始地址
页面在内存中的起始地址+页内偏移量=实际的物理地址
逻辑地址→物理地址,二进制转化
在计算机内部,地址是用二进制表示的, 如果页面大小刚好是2的整数幂,则计算机硬件可以很快速的把逻辑地址拆分成(页号,页内偏移量)
假设某计算机用32个二进制