« 上一篇下一篇 »

数据结构支持相邻空闲块的接合

界标记。在每个(不管是空闲的还是分配的)存储块的高低两端,我们都存放了重要信息。在块的两端都设置一个free/used位,用来标识当前该块是已用的(used)还是 空闲的(free)。在与每一个free/used位相邻的位置上存放了该块中的字节总数。
加快计算的方法之一就是使用并行技术,遗憾的是,开发可以利用并行机器的软件并不是容易的事情。把计算机过程分割为多个可以在不同并行处理器上执行的单元已经是很困难的事情了。但是这样分割还不能保证提高速度。我们必须把处理器之间的通信见到最小。实现网站建设中技术的个各种功能,快速地稳定掌握好不是一件容易的事情。

边界标记。在每个(不管是空闲的还是已分配的)存储块的高低两端,我们都存放了重要的信息。在块的两端都设置了一个free/used位,用来标识当前该块是已用的(used)还是 空闲的(free)。在与每一个free/used位相邻的位置上存放了该块中的字节总数。

一个双重链接的、嵌入式的空闲列表。各个空闲块(而不是已分配的块)还使用一个双重链表进行链接。这个链表的指针就存放在这些块中,比如说存放在紧挨着某一端边界标记的位置上。因此,不需要额外的空间来存放这个空闲块列表,尽管它的存在为块的大小设置了一个下界。即使数据对象只有一个字节,存储块也必须提供存放两个边界标记和两个指针的空间。空闲列表中的存储块的顺序没有确定。例如,这个列表可以按块的大小排序,因此可以支持best-fit放置策略。

管理和接合空闲空间

当一个对象通过手工方式回收时,存储管理器必须将该存储块设置为空闲的,以便它可以被 再次分配。在某些情况下,还可以将这个块和堆中的相邻块合并(接合)起来,构成一个更大的 块。这样做是有好处的。因为我们总能够用一个大的存储块来完成总量相等的多个小存储块所完成的工作,但是不能用很多个小存储块来保存一个大对象,而合并后的存储块就有可能做到。

如果我们为所有具有固定尺寸的存储块保留一个容器,如为小尺寸块所做的那样,那么我们可能倾向于不把相邻的该尺寸的块合并成为双倍大小的块。比较简单的做法是将所有同样大小的块全部按照需要放在多个页中,而不必接合。

那么,一个简单的分配/回收方案是维护一个位映射,其中的每个比特对应于容器中的一个块。1代表该块已被占用,0表示它是空闲的。当一个块被回收时,我们将它对应的1改为0。当我们需要分配一个存储块时,便找出任意一个相应比特为0的块,将这个位改为1,然后就可以使用该内存块了。如果没有空闲块,我们就获取一个新的页,将其分割成适当大小的存储块,同时扩展用于存储管理的位向量。

« 上一篇下一篇 »