小对象的分配技术(3/4)

来源:互联网 发布:淘宝店店铺介绍在哪写 编辑:程序博客网 时间:2024/04/27 17:02

3.SmallObjAllocator

如果第一次看到小型对象的分配细节,看完Chunk和FixedAllocator之后你一定很迷茫,在内存分配的起初两层,我们总是在研究固定大小的内存块,这似乎没有一点用处,大小一旦确定,你无法分配比blockSize大的内存块,即使是 blockSize得整数倍,因为一次只得到了一块内存,连续两次得到的内存块未必是连续的,你也不适合分配比blockSize小的内存块,这要浪费内存,而且很别扭。其实这都是因为Loki小对象分配器把Chunk和FixedAllocator做为原组使用了,真正分配任意大小内存的是SmallObjAllocator,看一下代码你就肯定明白了:

class SmallObjAllocator
{
public:
    SmallObjAllocator(std::size_t    chunkSize,std::size_t    maxObjectSize);
    
void*    Allocate(std::size_t    numBytes);
    
void    Deallocate(void*    p,std::size_t    size);
private:
    std::vector
<FixedAllocator>    pool_;
}
;

我们在构造函数里确定最大可分配的内存块大小,但是这并不意味着你只能分配不比maxObjectSize大的内存块,只是对于这样的内存块SmallObjAllocator转发给了系统的new。

我们已经知道,FixedAllocator只能分配固定大小的内存块,是的,到这里你明白了,pool_里有所有大小的Chunk,如此任意大小的块分配都可以转给合适的Chunk。在Deallocate里我们要求提供一个内存块大小的参数,避免pool_级别的遍历。

为了避免可能的内存浪费,pool_里的FixedAllocator并不是从1到maxObjectSize全部一次性分配的,一般情况下,一次性分配对内存的浪费是惊人的,相反,我们采用首次使用分配的策略。在首次使用的时候分配,依FixedAllocator里使用到的策略,我们对最后使用到的FixedAllocator记录以优化查询,最差情况下,SmallObjAllocator进行二分查找。

class SmallObjAllocator
{
public:
    ...
private:
    std::vector
<FixedAllocator>        pool_;
    FixedAllocator
*                    pLastAlloc_;
    FixedAllocator
*                    pLastDealloc_;
}
;
原创粉丝点击