目录
一、基本分页存储管理
固定分区会产生内部碎片,动态分区会产生外部碎片,这两种技术对内存的利用率都比较低。我们希望内存的使用能尽量避免碎片的产生,这就引入了分页的思想:把主存空间划分为大小相等且固定的块,块相对较小,作为主存的基本单位。每个进程也以块为单位进行划分,进程在执行时,以块为单位逐个申请主存中的块空间。
分页的方法从形式上看,像分区相等的固定分区技术,分页管理不会产生外部碎片。但它又有本质的不同点:块的大小相对分区要小很多,而且进程也按照块进行划分,进程运行时按块申请主存可用空间并执行。这样,进程只会在为最后一个不完整的块申请一个主存块空间时,才产生主存碎片,所以尽管会产生内部碎片,但这种碎片相对于进程来说也是很小的,每个进程平均只产生半个块大小的内部碎片(也称页内碎片)。
1. 分页存储的几个基本概念
【总结】:
连续分配:为用户进程分配的必须是一个连续的内存空间。
非连续分配:为用户进程分配的可以是一些分散的内存空间。
1)页面和页面大小
进程中的块称为页或页面(Page),内存中的块称为页框或页帧(Page Frame)。外存也以同样的单位进行划分,直接称为块或盘块(Block)。进程在执行时需要申请主存空间,即要为每个页面分配主存中的可用页框,这就产生了页和页框的一一对应。
为方便地址转换,页面大小应是 2 的整数幕。同时页面大小应该适中,页面太小会使进程的页面数过多,这样页表就会过长,占用大量内存,而且也会增加硬件地址转换的开销,降低页面换入/换出的效率;页面过大又会使页内碎片增多,降低内存的利用率。
2)页表
页表记录页面在内存中对应的物理块号,页表一般存放在内存中。
在配置页表后,进程执行时,通过查找该表,即可找到每页在内存中的物理块号。可见,页表的作用是实现从页号到物理块号的地址映射,如上图所示。
页表是由页表项组成的,页表项与地址都由两部分构成,而且第一部分都是页号,但页表项的第二部分是物理内存中的块号,而地址的第二部分是页内偏移;页表项的第二部分与地址的第二部分共同组成物理地址。
【思考】:
(a)每个页表项占多少字节?
页表项连续存放,因此页号可以是隐含的,不占存储空间(类比数组)
(b)如何实现地址的转换
进程在内存中连续存放时,操作系统是如何实现逻辑地址到物理地址的转换的?
将进程地址空间分页之后,操作系统该如何实现逻辑地址到物理地址的转换?
(c)如何确定一个逻辑地址对应的页号、页内偏移量?
在计算机内部,地址是用二进制表示的,如果页面大小刚好是 2 的整数幂,则计算机硬件可以很快速的把逻辑地址拆分成 (页号,页内偏移量) 。
结论:
-
如果每个页面大小为 2KB ,用二进制数表示逻辑地址,则末尾 K 位即为页内偏移量,其余部分就是页号
-
根据页号可以查询页表,而页表中记录的只是内存块号,而不是内存块的起始地址。J 号内存块的起始地址 = J × 内存块大小
-
如果页面大小刚好是 2 的整数幂,则只需把页表中记录的物理块号拼接上页内偏移量就能得到对应的物理地址。
(d)为何页面大小要取 2 的整数幂?
页面大小刚好是 2 的整数幂有什么好处?
① 逻辑地址的拆分更加迅速——如果每个页面大小为 2KB ,用二进制数表示逻辑地址,则末尾 K 位即为页内偏移量,其余部分就是页号。因此,如果让每个页面的大小为 2 的整数幂,计算机硬件就可以很方便地得出一个逻辑地址对应的页号和页内偏移量,而无需进行除法运算,从而提升了运行速度。
② 物理地址的计算更加迅速——根据逻辑地址得到页号,根据页号查询页表从而找到页面存放的内存块号,将二进制表示的内存块号和页内偏移量拼接起来,就可以得到最终的物理地址。