内存分配管理(一)

来源:互联网 发布:杭州百替生物数据造假 编辑:程序博客网 时间:2024/05/25 08:12

看jrtplib源码时,对其中的内存管理不理解,遂向高手请教,把所得记于此:


主要的两个类:

class RTPMemoryManager{public:RTPMemoryManager(){ }virtual ~RTPMemoryManager(){ }virtual void *AllocateBuffer(size_t numbytes, int memtype) = 0;virtual void FreeBuffer(void *buffer) = 0;};

class RTPMemoryObject{protected:#ifdef RTP_SUPPORT_MEMORYMANAGEMENTRTPMemoryObject(RTPMemoryManager *memmgr) : mgr(memmgr){ }#elseRTPMemoryObject(RTPMemoryManager *memmgr){ }#endif // RTP_SUPPORT_MEMORYMANAGEMENTvirtual ~RTPMemoryObject(){ }#ifdef RTP_SUPPORT_MEMORYMANAGEMENTRTPMemoryManager *GetMemoryManager() const{ return mgr; }void SetMemoryManager(RTPMemoryManager *m){ mgr = m; }#elseRTPMemoryManager *GetMemoryManager() const{ return 0; }void SetMemoryManager(RTPMemoryManager *m){ }#endif // RTP_SUPPORT_MEMORYMANAGEMENT#ifdef RTP_SUPPORT_MEMORYMANAGEMENTprivate:RTPMemoryManager *mgr;#endif // RTP_SUPPORT_MEMORYMANAGEMENT};

据说下面这个类RTPMemoryObkect的作用是为了把具体工作的类与RTPMemoryManager分离(设计模式->适配器模式)


首先,它有自己的new:

inline void *operator new[](size_t numbytes, RTPMemoryManager *mgr, int memtype){if (mgr == 0)return operator new[](numbytes);return mgr->AllocateBuffer(numbytes,memtype);}
重载 operator new 的参数个数是可以任意的 只需要保证第一个参数为 size_t, 返回类型为 void * 即可 而且其重载的参数类型也不必包含自定义类型 。

然后这样使用:

#define RTPNew(a,b) new(a,b)uint8_t *localhostname = RTPNew(GetMemoryManager(),RTPMEM_TYPE_OTHER) uint8_t [localhostnamelength+1];


真正的内存分配需要用户来完成,也就是上面的纯虚函数AllocateBuffer,jrtplib中有个example5,给出了示例:

class MyMemoryManager : public RTPMemoryManager{public:MyMemoryManager() { mutex.Init();alloccount = 0; freecount = 0; }~MyMemoryManager() { std::cout << "alloc: " << alloccount << " free: " << freecount << std::endl; }void *AllocateBuffer(size_t numbytes, int memtype){mutex.Lock();void *buf = malloc(numbytes);std::cout << "Allocated " << numbytes << " bytes at location " << buf << " (memtype = " << memtype << ")" << std::endl;alloccount++;mutex.Unlock();return buf;}void FreeBuffer(void *p){mutex.Lock();std::cout << "Freeing block " << p << std::endl;freecount++;free(p);mutex.Unlock();}private:int alloccount,freecount;JMutex mutex;};

最后这样使用:

MyMemoryManager mgr;RTPSession sess(0, &mgr);


这种方法很巧妙,也很难看懂,example里面的内存分配方式简易了点,自己实现时可以考虑内存池,因为RTP数据发送时申请和释放内存还是挺频繁的。