zoukankan      html  css  js  c++  java
  • leveldb分析——Arena内存管理

    leveldb中实现了一个简单的内存管理工具Arena,其基本思想为:先预先向系统申请一块内存,此后需要申请内存时,直接到预先分配的内存中申请。

    那么这样做的目的是什么呢?

    (1)避免了频率地进行malloc/new和free/delete操作,同时对于内存管理变得简单,对于内存的释放工作交给Arena。

    (2)避免造成大量的内存碎片。(还需去了解一下)

          

    下面看具体的源码分析:

    Arena定义:

    class Arena {
     public:
      Arena();
      ~Arena();
    
      // Return a pointer to a newly allocated memory block of "bytes" bytes.
      char* Allocate(size_t bytes);
    
      // Allocate memory with the normal alignment guarantees provided by malloc
      char* AllocateAligned(size_t bytes);
    
      // Returns an estimate of the total memory usage of data allocated
      // by the arena (including space allocated but not yet used for user
      // allocations).
      size_t MemoryUsage() const {
        return blocks_memory_ + blocks_.capacity() * sizeof(char*);
      }
    
     private:
      char* AllocateFallback(size_t bytes);
      char* AllocateNewBlock(size_t block_bytes);
    
      // 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_;
    
      // No copying allowed
      Arena(const Arena&);
      void operator=(const Arena&);
    };

    Arena提供两种分配方式:所分配的内存严格对齐、不一定严格对齐的分配方式。每次预先分配的4K(为什么是4K?)保存到blocks_ vector中,最后统一释放。这种内存管理方式是具有一定的适用范围,如需不断分配小内存,最终一并全释放的场景。对于leveldb来说,memtable恰好就是这样的,每次向memtable中insert一条k/v时,就申请一块内存,当memtable被flush到磁盘且不再使用时,将整个memtable释放掉。

    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);   //预先分配的不足
    }
    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;
    }

    下面来看下严格对齐的分配方式

    char* Arena::AllocateAligned(size_t bytes) {
      const int align = sizeof(void*);    // We'll align to pointer size
      assert((align & (align-1)) == 0);   // Pointer size should be a power of 2
      size_t current_mod = reinterpret_cast<uintptr_t>(alloc_ptr_) & (align-1);  ///计算出alloc_ptr_ % align 
    size_t slop
    = (current_mod == 0 ? 0 : align - current_mod); ///对齐还需要向前移动的大小
    size_t needed
    = bytes + slop;
    char* result; if (needed <= alloc_bytes_remaining_) { result = alloc_ptr_ + slop; alloc_ptr_ += needed; alloc_bytes_remaining_ -= needed; } else { // AllocateFallback always returned aligned memory result = AllocateFallback(bytes); } assert((reinterpret_cast<uintptr_t>(result) & (align-1)) == 0); return result; } char* Arena::AllocateNewBlock(size_t block_bytes) { char* result = new char[block_bytes]; blocks_memory_ += block_bytes; blocks_.push_back(result); return result; }
  • 相关阅读:
    Maximum Depth of Binary Tree
    Single Number
    Merge Two Sorted Lists
    Remove Nth Node From End of List
    Remove Element
    Remove Duplicates from Sorted List
    Add Two Numbers
    编译视频直播点播平台EasyDSS数据排序使用Go 语言 slice 类型排序的实现介绍
    RTMP协议视频直播点播平台EasyDSS在Linux系统中以服务启动报错can’t evaluate field RootPath in type*struct排查
    【解决方案】5G时代RTMP推流服务器/互联网直播点播平台EasyDSS实现360°全景摄像机VR直播
  • 原文地址:https://www.cnblogs.com/xey-csu/p/5060552.html
Copyright © 2011-2022 走看看