Boost.Interprocess使用手册翻译之九:内存分配算法(Memory allocation algorithms)

来源:互联网 发布:上海老房子集中地知乎 编辑:程序博客网 时间:2024/05/29 15:09

九.内存分配算法

simple_seq_fit:一个简单的共享内存管理算法

rbtree_best_fit:最适合的对数级时间复杂度分配

simple_seq_fit:一个简单的共享内存管理算法

此算法是连续适应(sequential fit)算法的一个变种,它使用单链表空闲内存缓冲区。此算法基于关于共享内存的文章“驯服共享内存(Taming Shared Memory)”。算法如下:

共享内存分割为数块空闲的共享内存,每一块都有一些控制数据和一些将被使用的内存字节。控制数据包含了一个指向下一个空闲块的指针(我们使用offset_ptr)和空闲块的大小。分配器包含了一个空闲块的单链表,它按照地址排序。最后一块总是指向第一块。


当某用户请求N字节内存,分配器遍历空闲块链表以寻找一块足够大的内存块。如果内存块的内存部分与请求的内存大小相同,则将此内存块从链表中移除同时返回一个指向此内存块内存部分的指针。如果内存部分的大小大于所需要的内存,我们分割此块内存为两部分,一个是申请的大小,另一个是剩余的大小。现在,我们获取到了大小正好的内存块,从链表中删除它然后将它交给用户。

当用户释放一个内存块,我们遍历链表(记住,链表是有序的),然后根据内存块的地址搜索其位置。一旦找到,如果可能的话,我们尝试将此内存块与其相邻块合并。

为简化操作,空闲内存块的大小被计算为“基本大小(basic_size)”的整数倍。基本大小是控制块对齐至机器最严格对齐的大小。

此算法是一个低尺寸开销算法,适合于简单分配方案。此算法应该仅在空间大小是最主要问题时使用,因为当内存碎片化时,此算法的性能会受到影响。此算法具有线性分配和释放时间,因此当分配数目很大时,用户应该使用一个更表现友好的算法。

在多数8字节对齐的32位系统下,“基本大小”是8字节。这意味着一次请求1字节的分配会导致创建一个16字节的内存块,其中8个字节是对用户可用的。一个8个字节的分配也会导致同样的16字节内存块。

rbtree_best_fit:最适合的对数级时间复杂度分配

此算法是一个高级算法,它使用红黑树按照大小来对空闲内存块排序。它允许对数复杂度分配。此外,维护一个所有内存块(空闲的和已分配的)的双向链表,以便当执行合并操作时允许对前后块能具有常量时间(constant-time)访问。

当不再被使用时,用于创建空闲节点红黑树的数据将被用户重写。它保持了内存大小开销低至双向链表开销,这是非常小的(两个指针)。基本方案如下:


此分配算法非常快并且很好的扩展了大共享内存片段和大数量分配。若要形成一个内存块,需要的最小内存大小是:双向链表和红黑树控制数据之和。内存块的大小是最严格对齐值的整数倍。

在多数8字节对齐的32位系统下,内存块的最小大小是24字节。当分配一个内存块,则关联红黑树的控制数据被用户改写(因为它仅被空闲块需要)。

在这些系统下,一个1字节的分配请求意味着:

  • 24字节内存用于形成一个内存块。
  • 它们中的16字节能够被用户使用。

对非常小的分配(<=8字节),此算法比简单连续适应算法浪费更多内存(多8个字节)。对大于8字节的分配,它们的内存开销是完全相同的。它是Boost.Interprocess托管内存片段的默认分配算法。

0 0
原创粉丝点击