C++的Slab分配器主要基于C语言的分配器之上 ,进行包装调用形成,而在调用C语言接口之前,需要进行重载C++中的new,delete函数接口(静态函数形式提供),也就是通过模板提供一层接口,这样在进行分配时,顺序如下:
1.调用重载的new接口
2.调用具体类new接口
析构时刚好顺序相反,具体的封装类如下:
1.首先提供一层对C语言接口封装的的类:
点击(此处)折叠或打开
- template <typename T>
- class _Slab
- {
- //protected:
- //friend class Singleton< _Slab<T> >;
- public:
- _Slab()
- {
-
- std::cout <<"T:"<<typeid(T).name()<<" size:"<<sizeof(T)<<std::endl;
- if((m_pSlabCache = umem_cache_create(typeid(T).name(),sizeof(T),ALIGN4,SLAB_NOSLEEP,NULL,NULL)) == NULL)
- std::cout <<"Create Slab Error"<<std::endl;
- }
-
- ~_Slab()
- {
- umem_cache_destroy(m_pSlabCache);
- }
- void* alloc(std::size_t size)
- {
- return umem_cache_alloc(m_pSlabCache);
- }
-
- void dealloc(void *p,std::size_t size)
- {
- umem_cache_free(m_pSlabCache,p);
- }
-
- private:
- umem_cache_t* m_pSlabCache;
- };
2.在此基础上提供一层针对new/delete的静态模板类接口:
- template <typename T>
- class Slab
- {
- public:
- static void* operator new(std::size_t size)
- {
- std::cout <<"operator new:"<<size<<std::endl;
- return Singleton < _Slab <T> >::getInstance()->alloc(size);
- }
- static void operator delete(void *p,std::size_t size)
- {
- std::cout << "delete" << std::endl;
- Singleton< _Slab <T> >::getInstance()->dealloc(p,size);
- }
-
- virtual ~Slab()
- {
- }
- };
3.上面的封装类采用了单例的方式提供,具体实现如下:
- template <typename T>
- class Singleton
- {
- public:
- static T* getInstance()
- {
- static T t;
- std::cout << typeid(T).name() << endl;
- return &t;
- }
- private:
- Singleton()
- {
- }
- Singleton(const Singleton&);
- Singleton& operator=(const Singleton &);
- ~Singleton()
- {
- }
- };
4.测试程序如下
- #include <iostream>
- using namespace std;
- #include "Slab.h"
- class A:public Slab<A>
- {
- public:
- A(int s):size(s)
- {
- std::cout << "class A"<<std::endl;
- }
-
- ~A()
- {
- std::cout << "class ~A"<<std::endl;
- }
-
- void show()
- {
- std::cout <<"size:"<<size<<std::endl;
- }
-
- private:
- int size;
- };
- int main(void)
- {
- //Slab<A> *pA = new Slab<A>();
- A *pA = new A(19);
-
- pA->show();
-
- delete pA;
-
- return 0;
- }
在编译时,gcc编译C语言中的slab文件:
- gcc -c slab.c -g
编译测试接口:
- g++ test_slab.cpp slab.o -g -lpthread
运行结果如下:
- operator new:8
- T:1A size:8
- 5_SlabI1AE
- class A
- size:19
- class ~A
- delete
- 5_SlabI1AE
这样就实现了一个面向对象的内存分配功能,这里只能针对某一类型的对象分配且内存大小小于4KB的对象.
完整原代码在这里: