Linux伙伴算法(Buddy Allocator)
来源:互联网 发布:软件转omtp ctia 编辑:程序博客网 时间:2024/06/08 19:39
该算法用于管理Linux物理内存,该算法的应用决定了内存分配的单位每次必为2的N次幂个页,如1、2、4、8、32页等。内存管理器初始化好之后,内存分配很简单,我的问题是,释放内存的时候如何做到高效呢?我很sb地想:
释放一块幂(order)为k内存,首先在k对应的链表中查找是否有相邻的块,如果有合并之。合并之后,再在order为k+1的链表中继续查找是否有相邻的块(此时为新的大块了),如此往复。
如果这是一个面试题目,我这么跟面试官说,他还可能以为我真的懂了呢!其实,我根本不懂。为什么这么说呢?问题就出在上面加粗的几个字上:查找。在我脑海中,这里的查找意味着遍历链表,通过对地址的判断找相邻项,直到找到为止。在内核中,如果不得不用这么sb的行为,早就有人将它用二叉树或hash里面的算法改写了!
于是读linux源码mm/page_alloc.c中的__free_pages_ok()函数,发现它怎么跑一遍就搞定了,list_add宏只调用过一次。按照我上面的想法,list_add必须频繁调用。有点神奇!于是进一步仔细阅读,它在while中反复调用了list_del宏,其余代码没仔细看,突然就明白了,哦,我傻!我的思维局限到free_list链表的操作中了,而我忘了,页面的搜索还可以根据mem_map来呀!当我把思维放到mem_map上来的时候发现一切都很很简单了:不就是线性地搜索相邻区域么?给定一个区域,并且知道它的长度,让你在其前后找出长度一样的相邻区域来,简单吧?
之所以能如此飘逸地完成此任务,与list_head结构的精巧设计是分不开的,最让我惊叹的是INIT_LIST_HEAD,list_empty两个简单的宏:
struct list_head *next, *prev;
};
#define INIT_LIST_HEAD(ptr) do { /
(ptr)->next = (ptr); (ptr)->prev = (ptr); /
} while (0)
static inline int list_empty(struct list_head *head)
{
return head->next == head;
}
简单吧?可别小看,简单中蕴藏着无限的飘逸啊。如果没有它们,上面的算法完全没有可行性。双向链表,好东西!
Linux还有个很值得注意的特征:同一组数据可能有多种数据结构来管理。有的管理器采用数组型的数据结构,有的管理器采用链表型数据结构,有的采用hash表的结构,有的还采用树状结构。通过综合不同管理器的特征,根据不同的应用场景,灵活选取不同的管理器,可以达到效率最优,是值得学习的好方法!
- Linux伙伴算法(Buddy Allocator)
- Linux Buddy Allocator
- 关于Buddy(伙伴)算法的讨论
- 关于Buddy(伙伴)算法的讨论
- 伙伴算法(Buddy)
- 伙伴算法 buddy system
- 操作系统 --- Buddy伙伴算法
- 内存管理算法--Buddy伙伴算法
- 内存管理算法--Buddy伙伴算法
- 内存管理算法--Buddy伙伴算法
- 内存管理算法--Buddy伙伴算法
- 寻找小伙伴--linux kernel buddy system
- Linux kernel memory management buddy system (linux内核内存管理的伙伴算法)
- 全面解析Linux 内核 3.10.x - 内存管理 - 伙伴系统算法(Buddy System)
- xv6的buddy(伙伴)系统源代码之buddy.h
- 内存管理之伙伴系统算法(The Buddy System Algorithm)
- Linux内存分配alloc_page和__get_free_page详注(伙伴管理系统Buddy)
- 堆管理算法中的Buddy System(伙伴系统)算法
- 自己搜集的面试英语材料,收藏中~
- TinyXML研究心得
- 如何在VS2008中创建模板,自动生成一些版权信息
- 免安装oracle客户端连接数据库服务器的方法
- 在VB6.0中实现大面积不规则区域的填充
- Linux伙伴算法(Buddy Allocator)
- vc6.0工程文件各种格式简单说明
- 如何连接oracle数据库及故障解决办法-总结
- awy5
- C++中操作符operator的两种用法
- 八名新人杀入十大最牛散户榜 刘元生卫冕
- c++串行化CArchive类的学习小结
- 80后北大才女唱《大龄文艺女青年之歌》走红
- 龙团长,“崇高”吗?