操作系统 知识点整理

CPU 访问内存整理

首先 CPU 在访问内存的时候都需要通过 MMU 把虚拟地址转化为物理地址,然后通过总线访问内存。MMU 开启后 CPU 看到的所有地址都是虚拟地址,CPU 把这个虚拟地址发给 MMU 后,MMU 会通过页表在页表里查出这个虚拟地址对应的物理地址是什么,从而去访问外面的 DDR(内存条)

参考:https://zhuanlan.zhihu.com/p/36139950

伙伴堆算法

伙伴堆算法的用途

每当分配和释放内存的时候系统都将遇到尾部碎片的问题,比如当请求一个页面的时候,即使系统可用页面总数足够多,但是无法分配大块连续的页面。也就是说可用页面会被一个或多个不连续的不可用页面拆开。使用伙伴算法就可以一定程度解决这种页面碎片的问题。

算法基本思想

Linux把所有的空闲页框分组为11个块链表,每个链表上的页框块是固定的。在第i条链表中每个页框块都包含2的i次方个连续页,其中i称为分配阶。

下面以一个例子,讲述伙伴算法的思想:假设要申请一个256个页,先从256个页框的链表中查找空闲块,如果没有,就去512个页框的链表中找,找到了则将页框块分为2个256个页框的块,一个分配给应用,另外一个移到256个页框的链表中。如果512个页框的链表中仍没有空闲块,继续向1024个页框的链表查找。如果1024块存在,则将其中的256页框作为请求返回,剩余的768分成256块和512块分别插到相应的链表中。如果仍然没有,则返回错误。

算法涉及的数据结构

Linux中伙伴堆算法的核心数据结构包含以下两个部分

1. free_area

//在mmzone.h中
#define MAX_ORDER 11
   struct zone
{
  ... ...
  struct free_area free_area[MAX_ORDER]... ...
};

内存分配与释放得原理
分配原理:假如系统需要4(2 * 2)个页面大小的内存块,该算法就到free_area[2]中查找,如果链表中有空闲块,就直接从中摘下并分配出去。如果没有,算法将顺着数组向上查找free_area[3],如果free_area[3]中有空闲块,则将其从链表中摘下,分成等大小的两部分,前四个页面作为一个块插入free_area[2],后4个页面分配出去,free_area[3]中也没有,就再向上查找,如果free_area[4]中有,就将这16(2 * 2 * 2 * 2)个页面等分成两份,前一半挂如free_area[3]的链表头部,后一半的8个页等分成两等分,前一半挂free_area[2]的链表中,后一半分配出去。假如free_area[4]也没有,则重复上面的过程,知道到达free_area数组的最后,如果还没有则放弃分配。

释放原理:内存的释放是分配的逆过程,也可以看作是伙伴的合并过程。当释放一个块时,先在其对应的链表中考查是否有伙伴存在,如果没有伙伴块,就直接把要释放的块挂入链表头;如果有,则从链表中摘下伙伴,合并成一个大块,然后继续考察合并后的块在更大一级链表中是否有伙伴存在,直到不能合并或者已经合并到了最大的块(2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2个页面)。整个过程中,位图扮演了重要的角色,位图的某一位对应两个互为伙伴的块,为1表示其中一块已经分配出去了,为0表示两块都空闲。伙伴中无论是分配还是释放都只是相对的位图进行异或操作。分配内存时对位图的是为释放过程服务,释放过程根据位图判断伙伴是否存在,如果对相应位的异或操作得1,则没有伙伴可以合并,如果异或操作得0,就进行合并,并且继续按这种方式合并伙伴,直到不能合并为止。

优点
1.解决内存碎片问题

2.避免把内存拆得太碎得同时,使内存的分配和释放过程迅速

缺点
1.虽然解决了内存碎片问题,但是该算法中,一个很小的块往往会阻碍一个大块的合并。(一片内存中仅一个小的内存块没有释放,旁边两个大的就不能合并。)

2.算法中有一定的浪费现象,伙伴算法是按2的幂次方大小进行分配内存块。

3.另外拆分和合并涉及到 较多的链表和位图操作,开销还是比较大的。

参考资料:https://www.jianshu.com/p/5e0cb078687c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值