内存管理之2:x86页式内存管理

news/2024/7/1 18:08:18

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

date: 2014-09-04 19:09

内存管理的目的是什么?内存管理本身就像一个外观模式,它隐藏底层细节而给应用程序提供一个统一易用的访问内存的接口。程序可以访问4G空间中的任意地址,但实际上物理内存可能只有几百M,这之间的矛盾该怎么解决?关键时刻,还是得抱硬盘的大腿。当可用内存不足时,将内存中不紧急的内容从内存中换出到磁盘上,从而腾出内存给更紧急的程序使用。当需要访问之前的内容时,再将磁盘中数据读入到内存中。内存管理就这样游走在进程的夹缝中,像魔术师一样硬生生的将几百M的内存用出“就像有4G内存一样”的效果。

核心问题来了,内存与磁盘的换入换出,该如何进行呢?显然,为了降低系统的复杂度,每次换入的基本单元其大小最好固定,不能太大,太大则影响换入速度,也不能太小,太小则换入太频繁。

那在段式管理中,该如何操作呢?将整个段一次性换入换出吗?可是每个段的长度不固定呀,而且整个段似乎也太大了。有人会说,段选择符最多支持8192个段(16位段寄存器的高13位用来索引段描述符),将4G的空间分摊到8192个段上,每个段的大小平均512K,可以满足要求了吧,但是CPU中只有6个段寄存器(CS/DS/SS/ES/GS/FS),要访问8192个段,需要频繁的切换段寄存器的内容,这也是一笔不小的开销呀。

为了解决这个问题,intel在386引入页式内存管理管理。由于有向前兼容的包袱,而且内存的“保护模式”也是建立在段式内存管理之上的,intel的页式管理不可能另起炉灶,只能在段式管理的基础上实现。某本书的作者说“加层是解决计算机问题的万金油”(原话可能不是这样),诚不我欺也。在段式内存管理中,访存指令中的“逻辑地址”经过段式转换,变成了发送到地址总线上的“物理地址”,这里加层处理就是:“逻辑地址”经过段式转换后,不再是“物理地址”而是“线性地址”,“线性地址”经过页式内存管理转换后才是最终发往地址总线上的“物理地址”。

页式内存管理中将4GB地址空间分割成4KB大小的页面,每个页面可以映射至内存中任意位置处的4KB物理空间(边界必须与4KB对齐)。在段式内存管理中,连续的逻辑地址映射到物理内存中也是连续的,而在页式内存管理中,连续的线性地址映射到物理内存中就不一定是连续的了,这也正是页式管理的灵活所在。由于页式管理的引入,32位的线性地址有了新的解释,如下:

线性地址的结构

其中高10位用作目录表索引,一共可以索引1024个目录项,目录项是一个32位的数,其中的高20位指向该目录项对应的页面表。同样页面表中有1024个页面项,每个页面项也是32位的数,其高20位指向物理页面的基地址(边界必须与4KB对齐),由于每个页面有4KB的空间,所以线性地址中的低12位用来表示在页面内的偏移。可见,如果我们可以获取到目录表的基地址,就可以将一个线性地址转换为对齐的物理地址了。刚刚好,intel的CPU中增加了一个寄存器CR3,指向当前页面表的基址。转换过程示意如下:

线性地址到物理地址转换

那么,为什么要分两个层次,先找到目录项再找到页面表,为什么不一步到位直接在页面表中找到对应的页面?这是出于空间效率的考虑。假定一步到位即目录表索引与页面表索引合二为一的话,页面表将有1K*1K=1M个页面表项,其能寻址的范围也是1M*4K=4G,但是考虑到一个进程不可能用到全部的4GB空间,所以某些页面表项是不可能被访问到的,那该页面表项所占用的空间(32位)白白浪费了。而在分层处理中就不存在类似的问题,如果目录表中的某个目录项为空,则不用设置其对应的包含1024个页面表项的页表,从而省下一部分空间。当然最坏的情况下,假定一个进程用满全部的4G空间,分两个层次会多出一个目录表(1024*4byte)的开销,不过这种概率是极低的。另外,一个页面是4KB,而一个页面表也是4KB,一个页面刚好可以存下了。这样一来,物理页面的起始地址以及页面表的基地址都与4KB对齐,地址的低12位都为0,而指向物理页面起始地址的页面表项以及指向页面表基地址的目录项,只需要有20位用于指针就够了,剩余的12位则可用于控制字段,目录项的结构体如下:

目录项结构

页表项的结构体与此类似,但没有PS字段,但D字段则有效(D字段在目录项中保留不用),表示该页面已经被写过,所以脏了。最低位的P,表示页面表或者相应的页面是否在内存中,如果P为0,则试图存取该页面时,CPU会触发缺页异常“Page Fault”,注意,这里的异常是内核有意为之,目的是进入内核的异常处理程序,将该页从磁盘上交换分区读入到内存中,并设置相应的基地址,并将P位设置成1。相反,当一个页面已经换出到交换分区后,可将P设置成0,表项中其余字段均无意义,所以可被用来临时存储其他信息,比如被换成的页面在磁盘上的位置信息等。

转载于:https://my.oschina.net/u/3857782/blog/1849748


http://www.niftyadmin.cn/n/2745321.html

相关文章

啊撒擦上去

/* 题目内容:在大学期间,经常需要租借教室。大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室。教室的大小功能不 同,借教室人的身份不同,借教室的手续也不一样。面对海量租借教室的信息&…

产妇坐月子里可以吃哪些水果?

产妇坐月子里可以吃哪些水果? 众所周知,生果的营养丰厚,滋味鲜美,人人爱吃。但是生果是生冷的食物,产妇吃了会怕着凉吗?专业的月子中心提示,产妇恰当吃些生果,不仅能添加营养,协助消化&#x…

功能性组件和Classes有什么不同?

React函数组件与React类有何不同? 有一段时间,规范的答案是类可以访问更多功能(如状态)。但是自从有了Hook后,这个答案变得不唯一了。 也许你听说其中一个表现更好。哪一个?许多此类基准都存在缺陷&#xf…

PHP代码常用注释规范(PHP Doc)

PHP代码常用注释规范(PHP Doc) 介绍几个常用的PHP注释 在PHP文件中使用该注释格式开始进行文件注释: /*** author 作者* copyright 版权信息* version 版本* 等等*/ 复制代码 描述一个类的注释: /*** Class 类名* package 命名空间…

Ruby 2.6.3 发布,引入日本新年号“令和”

开发四年只会写业务代码,分布式高并发都不会还做程序员? Ruby 2.6.3 已发布。新版本引入了新的日本年号:“令和”(Reiwa)。 主要更新内容: 升级支持的 Unicode 版本至 12.1 beta(#15195&#…

留学目的地选择之内华达州

留学目的地选择之内华达州 美国大学奖学金专家介绍到:内华达州(Nevada)是美国西部的一个州,北接俄勒冈州和爱达荷州,东界犹他州,东南邻亚利桑那州,西部与加利福尼亚州接壤。又称北美艾灌木丛州,以其发达的赌…

php课程 11-37 类和对象的关系是什么

php课程 11-37 类和对象的关系是什么 一、总结 一句话总结:类生成对象,对象是类的实例化,一定是先有类,后有对象,一定是先有标准,再有个体。 1、oop的三大优势是什么? 重用性,灵活性…

msdn 使用 SqlDataSource 控件选择数据

指定连接字符串 <asp:SqlDataSource ID"SqlDataSource1" runat"server" ConnectionString"<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand"SELECT * FROM [Categories]"></asp:SqlDataSo…