leveldb:Arena浅析

本文详细解读了leveldb中的 Arena 内存池,介绍了其内存分配接口、字节对齐逻辑以及优点和缺点。重点剖析了AllocateAligned函数,涉及内存对齐原理和优化策略。

引言

这是我关于Google leveldb的第一篇源码解读系列,我不会对所有源码进行解读,但我尽量保证讲到的点都比较清楚(在精不在多嘛)。

leveldb中的Arena是一个简单的、一次性的内存池的实现,它不像《STL源码剖析》中的内存池那样复杂、容错性强,因为它主要用于Memtable这种不断增加空间、空间满了之后一并存入SST的场景,因此它也是不支持手动调用Delete操作,由析构函数一起调用。

成员变量

  // Allocation state
  char* alloc_ptr_;
  size_t alloc_bytes_remaining_;

  // Array of new[] allocated memory blocks
  std::vector<char*> blocks_;

  // Total memory usage of the arena.
  std::atomic<size_t> memory_usage_;

Arena主体部分是一个std::vector<char*>,它用于管理所有分配的内存块。
alloc_ptr_alloc_bytes_remaining_都是当前正在使用的内存块的状态变量,用于指明可用内存的起点和剩余空间。
memory_usage_则是一个原子变量,用于在高并发场景下统计总体内存使用大小。
除此之外,Arena没有任何其他多余的成员变量,因为它是一次性的,并且存在一定浪费的,这点我们在文章后面讨论。

于是Arena大概长这样:
在这里插入图片描述

啥?这图画的居然还一长一短的,并且使用到的内存块居然不是最后一块,为什么呢,我们继续往下看吧!

MemoryUsage

Arena提供三大接口:Allocate、AllocateAligned和MemoryUsage。

我们将从最简单的MemoryUsage讲起。

  // Returns an estimate of the total memory usage of data allocated
  // by the arena.
  size_t MemoryUsage() const {
   
   
    return memory_usage_.load(std::memory_order_relaxed);
  }

由于没有deallocate操作,memory_usage_是只增不减的,增幅为block_bytes + sizeof(char*),其中sizeof(char*)被认为是vector中一个指针大小。

std::memory_order_relaxed只保证操作是原子的,但多核同步顺序是“relaxed”的,并不像std::memory_order_acquirestd::memory_order_release那样有更强的保证,感兴趣可以了解一下。

~Arena

// 需求:memtable不需要单次释放内存
Arena::~Arena() {
   
   
  for (size_t i = 0; i < blocks_.size(); i++) {
   
   
    delete[] blocks_[i];
  }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值