Chinaunix首页 | 论坛 | 博客
  • 博客访问: 491921
  • 博文数量: 72
  • 博客积分: 1851
  • 博客等级: 上尉
  • 技术积分: 1464
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-16 17:50
文章分类

全部博文(72)

文章存档

2013年(1)

2012年(17)

2011年(51)

2010年(3)

分类: C/C++

2012-05-03 20:22:37

C++Slab分配器主要基于C语言的分配器之上 ,进行包装调用形成,而在调用C语言接口之前,需要进行重载C++中的new,delete函数接口(静态函数形式提供),也就是通过模板提供一层接口,这样在进行分配时,顺序如下:

1.调用重载的new接口

2.调用具体类new接口

析构时刚好顺序相反,具体的封装类如下:

1.首先提供一层对C语言接口封装的的类:


点击(此处)折叠或打开

  1. template <typename T>
  2. class _Slab
  3. {
  4.     //protected:
  5.     //friend class Singleton< _Slab<T> >;
  6. public:
  7.     _Slab()
  8.     {
  9.         
  10.         std::cout <<"T:"<<typeid(T).name()<<" size:"<<sizeof(T)<<std::endl;
  11.         if((m_pSlabCache = umem_cache_create(typeid(T).name(),sizeof(T),ALIGN4,SLAB_NOSLEEP,NULL,NULL)) == NULL)
  12.             std::cout <<"Create Slab Error"<<std::endl;
  13.     }
  14.     
  15.     ~_Slab()
  16.     {
  17.         umem_cache_destroy(m_pSlabCache);
  18.     }

  19.     void* alloc(std::size_t size)
  20.     {
  21.         return umem_cache_alloc(m_pSlabCache);
  22.     }
  23.     
  24.     void dealloc(void *p,std::size_t size)
  25.     {
  26.         umem_cache_free(m_pSlabCache,p);
  27.     }
  28.     
  29. private:
  30.     umem_cache_t* m_pSlabCache;
  31. };

2.在此基础上提供一层针对new/delete的静态模板类接口:


  1. template <typename T>
  2. class Slab
  3. {
  4. public:
  5.     static void* operator new(std::size_t size)
  6.     {
  7.         std::cout <<"operator new:"<<size<<std::endl;
  8.         return Singleton < _Slab <T> >::getInstance()->alloc(size);
  9.     }
  10.     static void operator delete(void *p,std::size_t size)
  11.     {
  12.         std::cout << "delete" << std::endl;
  13.         Singleton< _Slab <T> >::getInstance()->dealloc(p,size);
  14.     }
  15.         
  16.     virtual ~Slab()
  17.     {
  18.     }
  19. };

3.上面的封装类采用了单例的方式提供,具体实现如下:


  1. template <typename T>
  2. class Singleton
  3. {
  4. public:
  5.     static T* getInstance()
  6.     {
  7.         static T t;
  8.         std::cout << typeid(T).name() << endl;
  9.         return &t;
  10.     }
  11. private:
  12.     Singleton()
  13.     {
  14.     }
  15.     Singleton(const Singleton&);
  16.     Singleton& operator=(const Singleton &);
  17.     ~Singleton()
  18.     {
  19.     }
  20. };

4.测试程序如下


  1. #include <iostream>
  2. using namespace std;
  3. #include "Slab.h"
  4. class A:public Slab<A>
  5. {
  6. public:
  7.     A(int s):size(s)
  8.     {
  9.         std::cout << "class A"<<std::endl;
  10.     }
  11.     
  12.     ~A()
  13.     {
  14.         std::cout << "class ~A"<<std::endl;
  15.     }
  16.    
  17.     void show()
  18.     {
  19.         std::cout <<"size:"<<size<<std::endl;
  20.     }
  21.   
  22. private:
  23.     int size;
  24. };

  25. int main(void)
  26. {
  27.     //Slab<A> *pA = new Slab<A>();
  28.     A *pA = new A(19);
  29.     
  30.     pA->show();
  31.     
  32.     delete pA;
  33.     
  34.     return 0;
  35. }

在编译时,gcc编译C语言中的slab文件:

  1. gcc -c slab.c -g

编译测试接口:

  1. g++ test_slab.cpp slab.o -g -lpthread

运行结果如下:


  1. operator new:8
  2. T:1A size:8
  3. 5_SlabI1AE
  4. class A
  5. size:19
  6. class ~A
  7. delete
  8. 5_SlabI1AE

这样就实现了一个面向对象的内存分配功能,这里只能针对某一类型的对象分配且内存大小小于4KB的对象.

完整原代码在这里:


阅读(2950) | 评论(5) | 转发(0) |
给主人留下些什么吧!~~

datao09072012-05-06 17:13:03

147189385: 完整的代码建议看一下,很好的.....
PS:这里使用的场景为服务器端当接受一个链接时,就是new一个Agent,为了防止大量的new/delete代价,就采用了slab分配器进行统一分配及迟回收的思想。

datao09072012-05-06 17:05:03

147189385: 完整的代码建议看一下,很好的.....
谢谢,我目前使用在自己的程序中,还是有些小bug,这里只是一种思想。

datao09072012-05-06 17:03:45

-小Y头-: 这里只能针对某一类型的对象分配且内存大小小于4KB的对象,这个有没有改善。。.....
也可以进行一些改善,不过还是有个上限,就是在slab中找起始地址上需要修改,应该也可以变成动态的,目前还不是很想弄出来。毕竟这种主要用于类的对象分配,一般都小于一页,用于减小页内碎片。可以参考论文:The Slab Allocator:An Object-Caching Kernel Memory Allocator。

-小Y头-2012-05-06 11:20:37

这里只能针对某一类型的对象分配且内存大小小于4KB的对象,这个有没有改善。。

1471893852012-05-04 22:18:22

完整的代码建议看一下,很好的