我的内存分配器

ObjectPool.h

#include <stddef.h>

class ObjectPool
{
private:
    ObjectPool(unsigned int step, unsigned int size);
    ~ObjectPool();
public:
    static ObjectPool& getSingleton();
    void* alloc(size_t size);
    void dealloc(void *ptr, size_t size);
private:
    class ObjectPoolImpl;
    ObjectPoolImpl *pool;
    unsigned int size;
    unsigned int step;
};
#define USEOBJECTPOOL static void* operator new(size_t size){ return ObjectPool::getSingleton().alloc(size); }static void operator delete(void *ptr, size_t size){ ObjectPool::getSingleton().dealloc(ptr, size); }

ObjectPool.cpp

#include "ObjectPool.h"
#include "KRYMalloc.h"
#include <stdio.h>

struct ChunkData
{
    unsigned int freeNodeSize;
    ChunkData *next;
};
struct FreeNode
{
    unsigned int id;
    int flag;
    FreeNode *next;
};
static unsigned int freeNodeOffect = offsetof(FreeNode, next);
static unsigned int numNodePerChunk = 256;
class ObjectPool::ObjectPoolImpl
{
public:
    ObjectPoolImpl(){}
    void init(unsigned int size)
    {
        chunkHead = 0;
        freeHead = 0;
        freeNodeSize = freeNodeOffect + size;
        if (sizeof(FreeNode*) > size)
        {
            freeNodeSize = freeNodeOffect + sizeof(FreeNode*);
        }
        chunkDataSize = sizeof(ChunkData) + freeNodeSize * numNodePerChunk;
    }
    ~ObjectPoolImpl()
    {
        ChunkData *cur = 0;
        while (chunkHead)
        {
            cur = chunkHead;
            chunkHead = chunkHead->next;
            KRY_free(cur);
        }
    }
    void* alloc()
    {
        FreeNode *node;
        ChunkData *chunk;
        char *temp;
        if (0 == freeHead)
        {
            chunk = (ChunkData*)KRY_malloc(chunkDataSize);
            chunk->freeNodeSize = numNodePerChunk;
            chunk->next = chunkHead;
            chunkHead = chunk;
            temp = (char*)chunk + sizeof(ChunkData);

            for (unsigned int i = 0; i < numNodePerChunk; ++i)
            {
                node = (FreeNode*)temp;
                node->id = i;
                node->flag = 0;
                node->next = freeHead;
                freeHead = node;
                temp += freeNodeSize;
            }
        }
        node = freeHead;
        freeHead = freeHead->next;

        temp = (char*)node - sizeof(ChunkData) - node->id * freeNodeSize;
        chunk = (ChunkData*)temp;
        chunk->freeNodeSize -= 1;

        if (0 != node->flag)
        {
            int error = 0;
            printf("object alloc error\n");
        }
        node->flag += 1;
        return &node->next;
    }
    void dealloc(void *ptr)
    {
        char *temp = (char*)ptr - freeNodeOffect;
        FreeNode *node = (FreeNode*)temp;

        temp -= sizeof(ChunkData) + node->id * freeNodeSize;
        ChunkData *chunk = (ChunkData*)temp;
        chunk->freeNodeSize += 1;

        if (1 != node->flag)
        {
            int error = 0;
            printf("object dealloc error\n");
        }
        node->flag -= 1;
        node->next = freeHead;
        freeHead = node;
    }
private:
    ChunkData *chunkHead;
    FreeNode *freeHead;
    unsigned int freeNodeSize;
    unsigned int chunkDataSize;
};

ObjectPool::ObjectPool(unsigned int step, unsigned int size)
{
    this->step = step;
    this->size = size;
    pool = new ObjectPoolImpl[size];
    for (unsigned int i = 0; i < size; ++i)
    {
        pool[i].init(step * i + step);
    }
}
ObjectPool::~ObjectPool()
{
    delete[] pool;
}
ObjectPool& ObjectPool::getSingleton()
{
    static ObjectPool singleton(sizeof(int*), 64);
    return singleton;
}
void* ObjectPool::alloc(size_t size)
{
    //return KRY_malloc(size);
    void *data = 0;
    if (size > this->step * this->size)
    {
        data = KRY_malloc(size);
    }
    else
    {
        data = pool[(size + step - 1) / step - 1].alloc();
    }
    return data;
}
void ObjectPool::dealloc(void *ptr, size_t size)
{
    //KRY_free(ptr); return;
    if (size > this->step * this->size)
    {
        KRY_free(ptr);
    }
    else
    {
        pool[(size + step - 1) / step - 1].dealloc(ptr);
    }
}
时间: 2024-07-29 06:23:44

我的内存分配器的相关文章

说下Redis采用不同内存分配器

参考文章: http://blog.sina.com.cn/s/blog_51df3eae01016peu.html 我们知道Redis并没有自己实现内存池,没有在标准的系统内存分配器上再加上自己的东西.所以系统内存分配器的性能及碎片率会对Redis造成一些性能上的影响. 在Redis的 zmalloc.c 源码中,我们可以看到如下代码: 49 #if defined(USE_TCMALLOC) 50 #define malloc(size) tc_malloc(size) 51 #define

简单的内存分配器

采用自定义的operator运算符实现自己的内存分配策略,在某些时候可以提高程序的效率.   C++中的new运算符,具体工作流程如下: 1.调用operator new申请原始内存 2.调用place new表达式,执行类的构造函数 3.返回内存地址 而delete操作符的工作是: 1.调用对象的析构函数 2.调用operator delete释放内存 例如: #include <iostream> using namespace std; class Test { public: Test

[转]STL的内存分配器

题记:内存管理一直是C/C++程序的红灯区.关于内存管理的话题,大致有两类侧重点,一类是内存的正确使用,例如C++中new和delete应该成对出现,用RAII技巧管理内存资源,auto_ptr等方面,很多C/C++书籍中都使用技巧的介绍.另一类是内存管理的实现,如linux内核的slab分配器,STL中的allocator实现,以及一些特定于某种对象的内存管理等.最近阅读了一些内存管理实现方面的资料和源码,整理了一下,汇编成一个系列介绍一些常用的内存管理策略. 1. STL容器简介 STL提供

内存分配器 (Memory Allocator)

对于大多数开发者而言,系统的内存分配就是一个黑盒子,就是几个API的调用.有你就给我,没有我就想别的办法.来UC前,我就是这样认为的.实际深入进去时,才发现这个领域里也是百家争鸣,非常热闹.有操作系统层面的内存分配器(Memory Allocator),有应用程序层面的,有为实时系统设计的,有为服务程序设计的.但他们的目的确认一样的,平衡内存分配的性能和提高内存使用的效率. 从浏览器开发的角度看,手机内存的增长速度相对于网页内容的增长仍然只是温暖水平,像Android这样的用内存大户更要算计着用

STL中的内存分配器原理

题记:内存管理一直是C/C++程序的红灯区.关于内存管理的话题,大致有两类侧重点,一类是内存的正确使用,例如C++中new和delete应该成对出现,用RAII技巧管理内存资源,auto_ptr等方面,很多C/C++书籍中都使用技巧的介绍.另一类是内存管理的实现,如linux内核的slab分配器,STL中的allocator实现,以及一些特定于某种对象的内存管理等.最近阅读了一些内存管理实现方面的资料和源码,整理了一下,汇编成一个系列介绍一些常用的内存管理策略. 1. STL容器简介 STL提供

内核的bootmem内存分配器【转】

转自:http://blog.csdn.net/zmxiangde_88/article/details/8041040 版权声明:本文为博主原创文章,未经博主允许不得转载. 在内核启动期间,伙伴系统内存管理器还没有建立之前,内核此时也要分配内存以及创建一些用于建立内存管理等机制的数据结构,此时内存分配和管理就是由bootmem内存分配器来完成的. bootmem的建立要求就是简单,越简单越好,因为一旦伙伴系统建立之后,就不需要bootmem了,因此对性能和通用性等要服从一切从简的原则.在了解这

遵照std::allocator实现自定制的内存分配器

下面是标准库STL中allocator的实现 template<class _Ty> class allocator : public _Allocator_base<_Ty> { // generic allocator for objects of class _Ty public: typedef allocator<_Ty> other; typedef _Allocator_base<_Ty> _Mybase; typedef typename _

[转]Linux内核最新的连续内存分配器(CMA)——避免预留大块内存

http://blog.csdn.net/21cnbao/article/details/7309757 在我们使用ARM等嵌入式Linux系统的时候,一个头疼的问题是GPU,Camera,HDMI等都需要预留大量连续内存,这部分内存平时不用, 但是一般的做法又必须先预留着.目前,Marek Szyprowski和Michal Nazarewicz实现了一套全新的Contiguous Memory Allocator.通过这套机制,我们可以做到不预留内存,这些内存平时是可用的,只有当需要的时候才

Nah Lock: 一个无锁的内存分配器

概述 我实现了两个完全无锁的内存分配器:_nalloc 和 nalloc.  我用benchmark工具对它们进行了一组综合性测试,并比较了它们的指标值. 与libc(glibc malloc)相比,第一个分配器测试结果很差,但是我从中学到了很多东西,然后我实现了第二个无锁分配器,随着核数增加至30,测试结果线性提高.核数增加至60,测试结果次线性提高,但是仅比tcmalloc好一点. 想要安装,输入命令: git clone ~apodolsk/repo/nalloc,阅读 README文档.

GPU内存分配器笔记

FDG: 大规模并行系统中的动态内存分配器由于需要全局同步(记账) ,导致性能急剧下降. 代码解析 1.superblock 类中包含两个变量,两个函数.默认superblock大小为2048 items[size]:存储 current:指向下一个未使用byte的索引 init(void):初始化superblock,将current=0,指向superblock第0byte alloc(size,offset,workID,id):在superblock里面分配内存,分配成功,返回指针,否则