Per-Class allocator(1)

小型内存池设计

内存池设计思路

  • 降低malloc调用次数
    为了减少malloc的次数,考虑能否先统一malloc一大块内存,然后我们自行在进行分割,然后再将分割的小内存块分配给使用者,而不用每次要使用内存的时候进行一次malloc,这样就可以提高效率。
  • 减少cookie数量

设计目的

  • 提高速度
  • 节省空间

例子

ref. C++ Primer 3/e, p.765

#include<cstddef>
#include<iostream>
using namespace std;

class Screen
{
public:
    Screen(int x):i(x){};
    int get() {return i;}
    
    void* operator new(size_t);
    void operator delete(void*, size_t);
private:
    Screen* next;//用来指向申请的内存池
    static Screen* freeStore;
    static const int screenChunk;
private:
    int i;//该类数据
};

Screen* Screen::freeStore = 0;
const int Screen::screenChunk = 24;

void* Screen::operator new(size_t size)
{
    Screen* p;
    if(!freeStore)
    {
        size_t chunk = screenChunk * size;//申请内存的大小
        freeStore = p = reinterpret_cast<Screen*>(new char[chunk]);
               //将一大块分割片片,当作linked list串接起来
        for(;p!=&freeStore[screenChunk-1];++p)
            p->next = p+1;
        p->next = 0;
    }
    p = freeStore;
    freeStore = freeStore->next;//指向链表首位
    return p;//把链表传回去
}

void Screen::operator delete(void *p, size_t)
{        //将指针回收到单向链表之中,放回前端
    (static_cast<Screen*>(p))->next = freeStore;
    freeStore = static_cast<Screen*>(p);    
} 

int main()
{
    cout<<sizeof(Screen)<<endl;
    
    size_t const N = 100;
    Screen* p[N];
    
    for(int i = 0; i<N; ++i)
        p[i] = new Screen(i);
        
    for(int i = 0; i<N; ++i)
        cout<<p[i]<<endl;
    for(int i = 0; i<N; ++i)
        delete p[i];
}

输出结果

输出结果

从图中可以看到,每个地址之间都相差8,说明没有带cookie。这是因为我们自己重载了new,如果没有的话,那么会自动调用global new,则每个间隔都会是16,因为包含了两个cookie。

启示

这个例子实际上已经将分配器的机制表达出来了,类似于开辟一个池塘的方式,再将池塘进行分割,分配给使用者。但这个例子也有一个缺点,类中还存在一个next指针,增加了类的大小。在下一个例子中,我们将尝试将这个next去除。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 155,869评论 24 680
  • 用一段时光,换一次懂得。愿有一个人,让你收起铅华,用心陪伴走过光阴。
    一抹夏优阅读 81评论 0 0
  • 文/文一米 上锁的日记本 不上锁的心 除了幸福 都与你无关 篮球场边的石凳旁 是我学习的秘密基地 球场上你飘洒的汗...
    文一米阅读 83评论 2 7
  • 1 大明湖畔的夏雨荷想了他一辈子也念了他一辈子,柔情似水的女子眼角爬满皱纹,笑容依旧却不再年轻,夏雨荷没有等到那个...
    六六六子阅读 295评论 0 0
  • 特别赞同郭德纲先生的一句话,就是其实我挺厌恶那些不明白任何情况就劝你要大度的人,你一定要离他远点,不然雷劈他的时候...
    宝菇凉先森阅读 201评论 0 2