levelDB源码笔记(2)-Arena

来源:互联网 发布:更新语句sql 编辑:程序博客网 时间:2024/05/17 03:51

Arena是个很简单的内存池实现,因为leveldb应用总是一次性销毁掉整个内存,所以这里连delete都没有。在析构里都一起删了就行

class Arena { public:char* Allocate(size_t bytes);...... private:  // Allocation state  char* alloc_ptr_;  size_t alloc_bytes_remaining_;  // Array of new[] allocated memory blocks  std::vector<char*> blocks_;  // Bytes of memory in blocks allocated so far  size_t blocks_memory_;};

有4个成员变量。blocks_,每个元素为指向一个内存块的指针。这些块中只有唯一一个是当前未放满的块,alloc_ptr指向该块空闲区开始的部分,alloc_bytes_remining为该块还剩余的空闲长度。

当外部请求一块新内存时。简单的比较请求长度和alloc_bytes_remning,如果够用,返回当前alloc_ptr,修改alloc_ptr和reminging。如果不够用,调用AllocateFallback申请新块

inline char* Arena::Allocate(size_t bytes) {  // The semantics of what to return are a bit messy if we allow  // 0-byte allocations, so we disallow them here (we don't need  // them for our internal use).  assert(bytes > 0);  if (bytes <= alloc_bytes_remaining_) {    char* result = alloc_ptr_;    alloc_ptr_ += bytes;    alloc_bytes_remaining_ -= bytes;    return result;  }  return AllocateFallback(bytes);}
AllocateFallback的实现如下。如果请求长度够长,直接申请一个新块返回。新块只包含该请求用的内存。alloc_ptr和remaining依然指向原来的块。如果请求长度较短,alloc_ptr和remaining将调整到指向新块中未被分配的部分。注意,这里没有像一般内存池常见的那样,维护一个数据结构来索引各个老块中尚未使用的部分,而是直接废弃不用了。只能说适用于某些应用。

char* Arena::AllocateFallback(size_t bytes) {  if (bytes > kBlockSize / 4) {    // Object is more than a quarter of our block size.  Allocate it separately    // to avoid wasting too much space in leftover bytes.    char* result = AllocateNewBlock(bytes);    return result;  }  // We waste the remaining space in the current block.  alloc_ptr_ = AllocateNewBlock(kBlockSize);  alloc_bytes_remaining_ = kBlockSize;  char* result = alloc_ptr_;  alloc_ptr_ += bytes;  alloc_bytes_remaining_ -= bytes;  return result;}



0 0
原创粉丝点击