Linux好友页面帧分配和释放

Linux好友页面帧分配和释放,linux,memory,linux-kernel,kernel,embedded-linux,Linux,Memory,Linux Kernel,Kernel,Embedded Linux,在阅读和理解linux内核时使用指南- 我有一些我想了解的关于页面分配和释放的好友系统 Linux解决外部碎片的技术 该问题基于著名的伙伴系统算法。全部免费 页面框架分为11个块列表,其中包含 1、2、4、8、16、32、64、128、256、512和1024连续页 分别是框架。[第8.1.7章] 这非常有意义,因为现在Linux可以快速地为分配请求提供服务,因为有不同的块大小可以满足不同的块大小请求 现在,假设系统启动,所有可用的页面都是免费的,并按照上面提到的11个组进行分组。现在让我们考

在阅读和理解linux内核时使用指南-

我有一些我想了解的关于页面分配和释放的好友系统

Linux解决外部碎片的技术 该问题基于著名的伙伴系统算法。全部免费 页面框架分为11个块列表,其中包含 1、2、4、8、16、32、64、128、256、512和1024连续页 分别是框架。[第8.1.7章]

这非常有意义,因为现在Linux可以快速地为分配请求提供服务,因为有不同的块大小可以满足不同的块大小请求

现在,假设系统启动,所有可用的页面都是免费的,并按照上面提到的11个组进行分组。现在让我们考虑一个过程,其中一个进程需要一个1阶的页面,然后释放它。根据free算法-

while (order < 10)
{ 
     buddy_idx = page_idx ^ (1 << order);
     buddy = base + buddy_idx;
     if (!page_is_buddy(buddy, order))
         break;
     list_del(&buddy->lru);
     zone->free_area[order].nr_free--;
     ClearPagePrivate(buddy);
     buddy->private = 0;
     page_idx &= buddy_idx;
     order++;
 }
while(订单<10)
{ 
buddy_idx=第页(1个lru);
区域->自由区[订单].nr_自由--;
ClearPagePrivate(好友);
好友->私人=0;
page_idx&=buddy_idx;
订单++;
}
因此,根据这个和我的场景,order 1区块(有史以来第一次分配)将与另一个order 1区块合并为order 2区块,尽管两个order 1区块尚未在分配阶段从order 2区块中拆分

这样,如果我继续分配然后释放一个块,系统很快就会达到一种状态,在这种状态下,所有内存块的顺序都是最大的,这似乎没有效率。我本以为只有当这两个伙伴之前从一个更大的顺序块中分离出来时,才会合并这两个伙伴,这样,初始默认状态将尽可能保留,整个系统将保持高效

我错过什么了吗?这个代码可能是错的吗?我不知道这段代码提供的另一个优点吗?

当有大量最小的顺序块可用时,假设这样的初始状态可能有点可疑。如果我没记错的话,内存块的分配应该从查找最小(相同大小)的组开始,然后查找更高阶的组以找到空闲块。如果找到的块比需要的块大,则会将其拆分,并更新相应的组。这并不明显,但整个过程可能从初始状态开始,此时只有最高阶块可用

我在文献中遇到的几个例子几乎描绘了相同的初始状态。在维基百科上可以找到一个雄辩的例子:。这个图表和描述说明了一个典型的情况

总之,我找不到任何证据来证明“初始默认状态”的假设。将较小的块从较大的块中拆分时效率降低的想法是最模糊的,可能值得单独讨论

编辑

从内核的角度来看,初始状态可能与假设进程看到的初始状态不同。比如说,系统启动,在某一点上有一块内存。然而,你的假设过程肯定不会是孤立的。在进程能够开始分配和释放任何内存块之前,内存分布可能会发生很大变化。可以肯定的是,内核,或者更准确地说,它的大多数子系统在初始化期间会请求大量大小不同的内存块,并且大量内存块将在相当长的时间内(可能在整个正常运行期间)归内核所有。因此,关键是,当您的流程开始时,好友系统很可能会“预热”,并且,实际上,有足够多的小块可用。但是,页面的伙伴(由您的流程获取)仍将属于各个子系统,并且,一旦您的流程决定释放其页面,这些伙伴将不会被批准为准备合并,即摘录中的
page\u is\u buddy()
将产生false。当然,如果您的流程确实成功地获取了现有的空闲块而不拆分高阶块,那么整个场景可能都是正确的

所以,关键是,您对初始好友分布的假设可能不是真正的初始状态。这只能是一种“热身”状态,在这种状态下,你确实可能会有一些小块,但他们的伙伴会很忙,因此会阻止所描述的不可控合并的假设过程

这里是
page\u buddy()。如果我没记错的话,内存块的分配应该从查找最小(相同大小)的组开始,然后查找更高阶的组以找到空闲块。如果找到的块比需要的块大,则会将其拆分,并更新相应的组。这并不明显,但整个过程可能从初始状态开始,此时只有最高阶块可用

我在文献中遇到的几个例子几乎描绘了相同的初始状态。在维基百科上可以找到一个雄辩的例子:。这个图表和描述说明了一个典型的情况

总之,我找不到任何证据来证明“初始默认状态”的假设。将较小的块从较大的块中拆分时效率降低的想法是最模糊的,可能值得单独讨论

编辑

从内核的角度来看,初始状态可能与假设进程看到的初始状态不同。比如说,系统启动,在某一点上有一块内存。然而,你的假设过程肯定不会是孤立的