一种简单的内存池设计方法

最近在rtp协议实现上碰到个小问题,就是接收数据后用于缓存的jtterbuffer动态分配的问题。原本的实现是静态分配的,预先分配一比较大的内存块,一年多的使用下来一直没有问题。但在最近增加了voip数据优先的flow control之后,视频数据的抖动变得厉害起来,原先的jitterbuffer经常会有满的现象,满了后就会造成丢帧,而视频数据只要一丢帧就必须丢掉接下的所有P帧,所以显示效果上变得不如以前好。但完全加大jitterbuffer又会变成另一种现象:延时会加大。

 

通过trace发现,jitterbuffer满的情况也较少出现,所以我就想到了用动态分配内存的方法,但是rtp数据接收非常频繁,我又不能不停new和delete,那怎么办呢? 联系到内存池的实现方法,我将实现稍稍改动了下,就比较完美满足了我的需求。

 

显示定义一个vector

 

std::vector<_block_t*> m_buffers;   // _block_t是一个数据结构,就是固定大小的内存块

 

接下来是molloc和free函数

 

// _mem_packet_t是需要使用内存的结构
_boolean_t memutil::mem_alloc( _mem_packet_t *pk, _uint32_t size )
{
 threadpool::util::auto_lock_t lock(m_lock_buffers);
 if(pk==NULL||size<=0)
      return false;

    //blk_cnt是需要分配的内存块数量
     _uint32_t blk_cnt = (size % ACT_BLOCK_SIZE)==0? (size/ACT_BLOCK_SIZE): ((size/ACT_BLOCK_SIZE) + 1);

 

    //当前已分配数量
     _uint32_t allocated_cnt = 0;

     unsigned long max_blk_count = m_buffers.size();

    //如果当前已经存在空余的内存块,则将指针传递给使用者,并标志为已分配

     for(register unsigned i=0; i<max_blk_count && allocated_cnt < blk_cnt; i++)
     {
          if(m_buffers[i]->m_flag == 0)
          {
               pk->m_block_list.push(m_buffers[i]);
               m_buffers[i]->m_flag = 1;
               m_buffers[i]->m_data_size = 0;
               allocated_cnt ++;
               m_block_used ++;
          }
     }

     

    //已经分配了足够的内存块,则返回true

     if (allocated_cnt == blk_cnt)
     {
          return true;
     }
     else
     {

           //未分配足够的内存块,说明m_buffers中已经没有足够内存块攻使用,则new一个新的内存块,加入到m_buffers列表末尾,然后将指针传递给使用者。
          for (int j=0; allocated_cnt<blk_cnt; j++)
          {
           _mem_block_t* blocktemp = new _mem_block_t;
           memset(blocktemp, 0x00, sizeof(_mem_block_t));
           m_buffers.push_back(blocktemp);
           pk->m_block_list.push(blocktemp);
           blocktemp->m_flag = 1;
           blocktemp->m_data_size = 0;
           allocated_cnt ++ ;
           m_block_used ++ ;
          }
     }
     return true;
}

 

 

_boolean_t memutil::mem_free( _mem_packet_t *pk )
{
 threadpool::util::auto_lock_t lock(m_lock_buffers);
     if(pk==NULL)
          return false;

    

    // 释放的过程同内存池实现基本相同,只是将内存块标记为未使用,使用者将其指针释放。
     for(;;)

    {
          _mem_block_t * blk = pk->m_block_list.pop();
          if(blk == 0)
               break;
          if(blk->m_flag == 1){
           blk->m_flag = 0;
           blk->m_data_size = 0;
           m_block_used --;
          }
     }
     return true;
}

 

而真正的内存释放在memutil的析构函数中,这样每个内存块的new和delete都只用使用一次,大大提高了速度。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值