Linux内存管理中的伙伴算法原理

需积分: 49 7 下载量 85 浏览量 更新于2024-09-14 收藏 307KB PDF 举报
Linux内存管理伙伴算法 Linux内存管理伙伴算法是Linux内核中的一种内存管理机制,该算法的主要任务包括遵从CPU的MMU机制、合理、有效、快速地管理内存、实现内存保护机制、实现虚拟内存、共享和重定位。伙伴算法是一种非常简单的内存分配算法,它的用途主要是尽可能减少外部碎片,同时允许快速分配与回收物理页面。 伙伴系统(Buddy System)是Linux内核中的一种内存管理机制,它的主要原理是将空闲的物理页面组织成不同的链表,每个链表中都包含着相同大小的空闲块。这样当需要分配内存时,可以快速地找到合适的空闲块,减少外部碎片的产生。 在伙伴算法中,每个链表都对应着一个特定的大小的空闲块,例如2个页面大小的空闲块、4个页面大小的空闲块等。当需要分配内存时,系统会首先检查是否有合适的空闲块,如果有,则分配给用户,否则将向下一个级别的链表中查找。例如,如果需要分配4个页面的内存,系统会首先检查order(1)链表中是否有合适的空闲块,如果有,则分配给用户,否则将向下一个级别的链表中查找,直到找到合适的空闲块。 伙伴算法的优点包括: 1. 减少外部碎片:伙伴算法可以减少外部碎片的产生,因为它可以快速地找到合适的空闲块,并将其分配给用户。 2. 快速分配与回收:伙伴算法可以快速地分配和回收物理页面,从而提高了系统的性能。 3. 实现虚拟内存:伙伴算法可以实现虚拟内存,允许用户使用超过物理内存大小的内存空间。 伙伴算法是Linux内核中的一种非常重要的内存管理机制,它可以减少外部碎片,快速分配和回收物理页面,实现虚拟内存等功能,因此在Linux内核中发挥着重要的作用。 在Linux内核中,伙伴算法的实现主要是通过伙伴系统(Buddy System)来实现的。伙伴系统将空闲的物理页面组织成不同的链表,每个链表中都包含着相同大小的空闲块。这样当需要分配内存时,可以快速地找到合适的空闲块,减少外部碎片的产生。 在实际应用中,伙伴算法可以用于各种需要快速分配和回收内存的场景,例如数据库系统、Web服务器等。它可以帮助提高系统的性能和可靠性,减少系统的崩溃和错误。 Linux内存管理伙伴算法是Linux内核中的一种非常重要的内存管理机制,它可以减少外部碎片,快速分配和回收物理页面,实现虚拟内存等功能,因此在Linux内核中发挥着重要的作用。
2018-08-08 上传
这个内存分配器需要是非入侵式的,即不在要分配的内存块中写 cookie 。 而我的需求中,需要被管理的内存块都是很规则的,成 2 的整数次幂的长度。buddy memory allocation 刚好适用。 算法很简单,就是每次把一个正内存块对半切分,一直切到需要的大小分配出去。回收的时候,如果跟它配对的块也是未被使用的,就合并成一个大的块。标准算法下,分配和释放的时间复杂度都是 O(log N) ,N 不会特别大。算法的优点是碎片率很小。而且很容易做成非入侵式的,不用在被管理的内存上保存 cookie 。只需要额外开辟一个二叉树记录内存使用状态即可。 我吃完饭简单 google 了一下,没有立刻找到满足我要求的现成代码。心里估算了一下,C 代码量应该在 200 行以下,我大概可以在 1 小时内写完。所以就毫不犹豫的实现了一份。 然后,自然是开源了。有兴趣的同学可以去 github 拿一份。这样就省得到再需要时再造轮子了。嘿嘿。 btw, 当然这块代码有许多值得优化的地方,比如可以把里面的递归优化成循环回溯。这个算法我读初中时经常写。因为初一那个时候参加信息学奥赛时用的 basic 不支持局部变量,全部变量都是全局的,很难实现递归。所以早期我都不用递归遍历二叉树的,感觉写起来好麻烦。 不过循环回溯遍历树应该是比递归快不少的,因为减少了许多不必要的环境变量压栈,对不支持 closure 的 C 语言尤其是。 这个库用起来很简单。它并不实际管理内存(它不侵入被管理的内存)。你可以设想你另外有一大块内存是由许多最小单位块合起来的。你可以假设最小单位是 1K 。那么用 buddy_new(10) 就可以帮你管理 1024K 内存。 buddy_alloc 可以请求若干个最小单位块,返回一个序号。然后用户可以自己去大内存上索引出来用。用完调用 buddy_free 归还即可。 为了调试方便,我还提供了 buddy_dump 打印二叉树的细节,可以直观的看出那些内存区域未被使用,哪些已经被占用。 ps. 果然,写这篇 blog 花掉的时间比完成这些代码时间更长。代码也如我所料的没有超过 200 行。看看,把东西描述清楚就是比实现一个东西要花更长的时间,这就是项目人多反而做的慢的原因之一吧。