内存管理强化
计算导图
- 虚拟地址总位数计算:
如果是一级页表,虚拟地址总位数=页号+页内偏移量
如果是二级页表,虚拟地址总位数=页目录号(也就是一级页表)+页号(二级页表)+页内偏移量- 页表大小计算:
页表大小=页表项数量【2的页目录号次方】 x 页表项的大小
二级页表大小也是同理。根据页号and页表项长度来计算- 二级页表中,逻辑页号/虚页号的大小
逻辑页号的位数=页目录号+页号- 页面大小/页框大小:
页面大小=2的页内偏移量次方- 物理地址
通过页内偏移量and页框号来获取- 页表项的物理地址:
页表项的起始物理地址+页表项长度 x 页号 = 页表项的物理地址
进而就可以找到页表项的具体内容- 页表项的内容
页号【隐含】、页框号【表示这个页号存放在内存的哪个页框里面】、有效位、修改位【调出时候用】、
其他:
【 1.比如外存的存储地址,就是说我这个页面发生缺页的时候,他在外存当中的哪一个块当中】
【2. 置换算法相关的信息,如记录每个页表项多久没有被访问过,方便后期置换】
二级页表具体计算流程:
- 一级页目录表中的每一个项都保存着一个二级页表的地址
【一级页目录项的物理地址】=【页目录表的起始物理地址】+ 【页目录号】X【页目录项的长度】
从而找到页目录项的具体内容【也就是二级页表的页框号=二级页表项的起始物理地址】- 二级页表项的起始物理地址+页表项长度 x 页号 = 页表项的物理地址
进而就可以找到页表项的具体内容
页表始址
当一个进程正在运行的时候,那么页表始址寄存器里面保存的就是页表的起始地址
而一个进程如果此时不运行,他的页表始址存放在进程的PCB中。等这个进程被调用的时候,OS将这个页表始址从PCB中读出来,然后写入页表始址寄存器里面
当CPU执行某一条指令时候,取出他的虚拟地址,然后进行拆分,先在内存中进行查找。查快表没找到,然后查慢表,发现缺页,说明这个页面没有调入内存。这时候就发生了缺页异常,需要读取磁盘进行调页。
页表中每一个页号都会对应他在内存中的【页框号】和磁盘中的【块号】
注意:调页的原理:
- 如果内存中有空闲页框,直接把页表中给的页号对应的磁盘中的【块号】调入内存的空闲页框中,然后修改该页表项的页框号就可以了
- 如果内存中没有空闲页框,就需要页面置换。比如淘汰2号页面,先看2号页表项的【修改位】,如果修改位=1,就需要把2号页面写回磁盘。假设2号页面在内存的【6号页框】,在磁盘的【7号块】。我们就需要把内存6号页框的数据写回到磁盘的7号块,然后设页表中2号页表项的有效位=0,这时候就可以将磁盘中的块调入内存
页表也是存放在内存中的, 所以比如在访问一个【数组】的时候【只知道虚拟地址情况下,数组保存在一个页框中】 第一次都会先【访存一次】来查页表,从而知道物理地址,然后再根据PA来第二次访存查找数据 查第二个数据的时候,直接查【快表】就能知道PA,然后访存来查数据