操作系统拾遗-离散内存管理

os中的分页算法

分页算法的背景

  • 为什么要有分页算法?

    为了打破线性地址和真实物理地址一一绑定的关系,

  • 为什么要打破这样的关系?

    连续内存模型无法很好的处理一些碎片问题,例如100MB内存中实际空间只用了70MB,但是剩下30MB均为碎片内存,很可能无法读入一个20MB的程序,即使内存空间剩余量远不止20MB。

  • 期望的模型?

    能有一种离散的内存模型,同一个程序可以按一定单位分布在内存不同处。

离散内存管理

段式管理

操作系统将内存以段(Segment)为单位划分,例如分为代码段,数据段,堆栈等,这样去划分一个程序,就初步做到了将一个进程离散的分割,经过这样的分割,内存的逻辑地址也就自然而然的分为两部分,前一部分为段基址,后一部分为段内便宜,元组模型为:<segment-number, offset>。

当CPU得到一个逻辑地址时,定位过程如图所示:


分段算法下的逻辑地址处理算法

首先一个逻辑地址分为两部分,s代表segment表中的偏移量,d代表基于segement的基址,还需要便宜多少的地址,对一个逻辑地址,首先根据s得到段基址base,之后判断d是否有超过这个段所限制的偏移量,如果没有超过,则将base和d相加得到物理地址。

段式管理的优点

  • 将内存分为几个大块,可以根据每个块的特性,进行专门的管理,例如访问控制等。

  • 一个进程可以分割为多个部分进行离散存储,可以一定程度上缓解内存碎片的问题。

段式管理的不足

  • 对内存单位的划分太过于粗糙,内存碎片问题仍然存在。

  • 在一个段内,空间利用率仍然是个头疼的问题,例如一个64mb的段,在这个段内,又回到了连续内存分配中出现的老问题,first fitting?best fitting?least fitting?

段页式管理

段的存在使得操作系统在大体上可以对不同内存区域进行定制化管理,也使得程序无需在一个连续内存上全部加载,但是这样的控制粒度来说还是太粗了,所以空间碎片问题还是大量存在,而页式管理就能更加精细的对内存进行管理。

开启分页功能的操作系统的内存访问方式如下,由段基址+段内偏移得到一个逻辑地址,再有这个逻辑地址查询页表找到对应的页表项,这个页表项所指向的地址才是真正的物理地址,所以段基址+段内偏移所得到的地址也称作为虚拟地址。

一级分页算法

所谓一级分页算法,就是在MMU计算得出线性地址和实际物理地址之间只有一层映射关系,也就是做了一层『目录』,如图所示

一级分页算法示意图

cpu得到一个逻辑地址,逻辑地址分为两部分,第一部分p为在页表中的偏移量,根据页表基址+偏移量p得到一个地址f,d为在此页表项基址f基础之上的偏移量,页表(page table)的地址一般放在寄存器中。

为什么要做这样的一层映射?

  • 解除了线性地址和物理地址一一绑定的关系,连续的逻辑地址映射到离散的物理地址,用户所见的地址仍然是连续的,与过去『线性地址==物理地址』无差异,用户层面对此改变无感知,但是操作系统底层的存储由连续存储转变为了离散存储,这样的好处就是避免了碎片化内存管理的问题:『明明当前所剩内存空间足够,但却没有一块完整的区域能够加载新进程』。

  • 所有程序理论上都可以占用整个内存空间,为后续支持虚拟内存技术做下铺垫(最大限度的利用os的资源)。

这样做随之而来带来的问题是什么?

  • 每一次的内存访问都需要经过页表再进行物理地址访问,等于说一次内存访问需要原来两次内存访问的开销。

  • 需要更多的内存管理开销,额外维护了一张页表,当前操作系统每一页的大小为4kb,即2的12次方,在32位操作系统中,一共有2的(32-12)次方个页需要维护,即有2的20次方个页,每个页需要有一个指针指向其所在位置,在32位操作系统中,一个指针的大小为4字节,所以维护一张页表需要4字节*2^20,总共4MB。32系统总内存为4GB,4MB的页表还在接受范围之内。

  • 一级页表需要全部预加载,因为一个进程理论上可能需要用到整个4GB的地址空间,所以无论是什么样的进程,4MB的页表必须加载入内存。当程序非常小,例如hello world这种几KB的程序也同样需要4MB的页表,非常浪费。

  • 每一个进程都需要一张这样的页表,当进程数增加时,页表开销增大。

改进目标?

  • 做一层缓存,将那些访问过的地址进行缓存,尽可能减少页表计算的开销。

  • 页表需要动态分配,如同lazy initialize一样,而不是全部预加载。

  • 页表太大,每一个进程都得对应一张这样的页表,进程多了所占用的内存还是非常可观的,最好能减小页表大小。

TLB(translation look-aside buffer)

开门见山的说,TLB是硬件层面的缓存,而不是软件层面的缓存,原因如下。

在应用层中,对热点数据的缓存是非常常见的做法,例如java中可以用一个简单的hashmap做缓存,也有redis这种内存数据库来做缓存的,核心的解决思路都是一样的,对热点数据进行记录,以节约下次查询时的访问开销,做法也大同小异,无非是在内存中构建一个key-value的数据结构。但是在分页机制中,用内存作为缓存的落脚点几乎没什么意义,原先的流程是查询页表再去访问物理地址,页表本身就在内存中,如果还是在内存中简单加入一个key-value的键值对去做缓存,访问流程变成了首先去查询缓存,如果命中,则访问物理地址,如果没有命中,则访问页表进行地址计算,内存访问开销并没有什么实质性的提升,反而内存的访问次数还多了一次。这个问题出现的本质原因就是在于传统应用层做缓存是为了能够减少对底层存储系统的访问(例如数据库,数据库的吞吐量远低于内存),但是在分页算法中,本身就是在访问内存,所以直接在内存中做缓存是毫无意义的。

正因为如此,在CPU中就加入了一个TLB这样的硬件缓存设备,访问速度很快,功耗和成本也高,所以TLB不会太大。

其访问过程没有太多好说的,就是一个硬件方面的缓存处理。

TLB示意图

多级分页算法

所谓的多级分页算法,就是在原有一层映射的基础上,再增加一层映射,以二级页表为例,如图所示

多级分页算法示意图
二级分页算法下逻辑地址的划分

一个逻辑地址被分为了三部分,p1代表第一级页目录的偏移量,p2代表页表项的偏移量,得到一个页地址后,再偏移d个单位即为真实物理地址。

多级页表具体是如何实现的?

  • 以二级页表为例,还是32位系统,页的大小仍然是4kb,也就是2的12次方,还是需要2的20次方个地址需要保存,高20位以10位为截断点,即第一级页表,也就是页目录项,数量为2的10次方,第二级页表,也就是页表,数量也为2的10次方,即均为1024个指针,可以理解为一个大小为1024*4字节即4kb的数组,数组的每一项都是一个int指针,指向一个同样大小为4kb的数组的起始地址。

简单的说,在二级分页中,地址的变化是 段基址+段偏移——>线性地址——>找到对应页目录——>找到对应页表项——>真实物理地址。

多级页表有解决一级分页的问题吗?

  • 与一级分页算法相同,第一级页表必须全部预加载,但是二级之后的页表无须预加载,而此时的一级页表大小远远小于在一级分页算法中的页表大小,以二级分页为例,第一级页表(页表项)包含2的10次方个地址,每个地址大小为4字节,所以整个第一节页表的大小为4KB,相较于一级分页算法的4MB有了非常显著的缩小。

反置页表

在计算机的世界中,为了解决一个问题,随之必然而然的就会带了一个新的问题,这是亘古不变的哲理,取舍就在于新问题和老问题你可以容忍哪一个了。

多级页表的引入是为了解决一级分页中的一些问题,也一定程度上缓解了原算法的一些问题,但是随之而来的问题也很明显,每一个进程都各自拥有一份多级页表,当虚拟地址空间增大到64bit,进程数量增加,分级级数时(例如四级五级分页),对内存造成的压力会随之增加的,这个问题的根本原因就在于,在多级分页算法中,page table的大小与逻辑地址空间是正相关的,而反置页表算法的解决思路是与“物理地址空间”绑定,页表的大小只与物理地址空间有关。

算法示意图如下:


反置页表算法示意图

逻辑地址被分为三部分,pid代表进程id,p代表page-number,d表示偏移量,其中<pid,page-number>用于在page table做匹配,如果匹配到了,那么该元组在page table中的偏移量i即作为页帧base地址,与d组成物理地址,作为对比,原先的分页算法将逻辑地址分为<virtual page-number (p), offset (d)>。通常会用hash算法提升这个匹配过程的效率,但即使这样,匹配效率也无法和原先的算法相比。

这样的算法的确解决了虚拟空间地址膨胀而导致页表所占内存急剧上升的问题,但是随之而来带来的缺陷也是非常明显,以我的理解,这样通过进程id和物理页帧做关联,一个物理页帧只和一个进程相绑定,一些内存共享,内存映射实现的复杂度肯定会随之而上升。Linux并没有采用反置页表这种算法,而是采取了多级分页算法。

总结

前两年上完操作系统的课感觉迷迷糊糊的有点懂,最近去回顾这些知识发现自己的理解还不够到位,于是就想整理下这些知识点。整个内存管理涉及到的一些算法我在这稍微整理了下,本来是想整理下一级分页和多级分页的差异,后续看着文章不够完整又补充了TLB和反置页表的资料,这篇文章不是引人入胜的从无到有的基础讲解,在我的理解看来更像是一篇对比,或者说各个算法不断冲突解决矛盾的,操作系统的哲学也就在这里,不断的产生的矛盾,不断的去解决,所有的方案都是在折中。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容

  • 操作系统对内存的管理 没有内存抽象的年代 在早些的操作系统中,并没有引入内存抽象的概念。程序直接访问和操作的都是物...
    Mr槑阅读 16,663评论 3 24
  • 操作系统概论 操作系统的概念 操作系统是指控制和管理计算机的软硬件资源,并合理的组织调度计算机的工作和资源的分配,...
    野狗子嗷嗷嗷阅读 11,889评论 3 34
  • 作为一个好男生,他们愿意为自己喜欢的女生付出一切,真心去对待那个女生,为什么还是没有交到女朋友?
    芯窝阅读 247评论 0 2
  • 为什么要读这本书? 从张家口之行回来后,我内心深处的不安越来越强烈。在和身边朋友的相处虽然说很融洽,但是我的内心还...
    GeekShow阅读 153评论 0 0
  • 感恩爱不完的课程 感恩,锦明老师昨晚耐心的给我们讲课整整为我们讲了四个多小时,课程结束都已经12点多了,认真听完锦...
    戴智英_六中换_醉美瑜伽阅读 134评论 2 2