发布网友 发布时间:2022-04-23 05:14
共5个回答
懂视网 时间:2022-05-03 14:30
内存分配管理器,主要为skiplist即Memtable服务而不是整个项目。申请内存时,将申请到的内存直接放入vector中,在Arena的生命周期结束后,统一释放掉所有申请的内存,内部结构如下图:
首先看一下内部成员
// 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.
//
// TODO(costan): This member is accessed via atomics, but the others are
// accessed without any locking. Is this OK?
std::atomic<size_t> memory_usage_;
构造函数和析构函数
Arena::Arena() // vector调用默认构造函数初始化
: alloc_ptr_(nullptr), alloc_bytes_remaining_(0), memory_usage_(0) {}
Arena::~Arena() {
for (size_t i = 0; i < blocks_.size(); i++) {
delete[] blocks_[i];
}
}
拷贝构造和拷贝赋值
Arena(const Arena&) = delete;
Arena& operator=(const Arena&) = delete;
主要对外接口
// 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);
具体实现如下:
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()分配内存:
具体实现如下:
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;
}
其中分配新内存块实现如下:
memory_order_relaxed:针对只要求原子操作,除此之外不需要其它同步保证,计数器是一种典型应用场景。
char* Arena::AllocateNewBlock(size_t block_bytes) {
char *result = new char[block_bytes];
blocks_.push_back(result); // 申请块放入vector,以便析构函数释放内存
memory_usage_.fetch_add(block_bytes + sizeof(char*),
std::memory_order_relaxed);
return result;
}
对齐内存分配
char* Arena::AllocateAligned(size_t bytes) {
const int align = (sizeof(void*) > 8) ? sizeof(void*) : 8; // 与系统相关,4或8
static_assert((align & (align - 1)) == 0,
"Pointer size should be a power of 2"); // 确保是2的指数次方
size_t current_mod = reinterpret_cast<uintptr_t>(alloc_ptr_) & (align - 1); // 当前指针模对齐值
size_t slop = (current_mod == 0 ? 0 : align - current_mod); // 还差slop个字节对齐
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;
}
读取内存使用
// 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);
}
【LevelDB源码阅读】Arena
标签:释放 结构 code 系统 access pre leveldb tin alignment
热心网友 时间:2022-05-03 11:38
LEVEL的意思:
n.水平,水准;水平线,水平面;水平仪;[物]电平。
adj.水平的;同高度的;平均的;平稳的。
vt.使同等;对准;弄平。
vi.拉平;(用*等)瞄准(与 at 连用);变得平坦;将(话、批评等)对准目标。
vi.瞄准;拉平;变得平坦。
音标:level英 [ˈlevl] 美 [ˈlɛvəl]
level的用法示例如下:
He forced his voice to remain level.
他竭力使自己的语气保持平静。
level第三人称单数: levels 复数: levels 现在分词: levelling 过去式: levelled 过去分词: levelled。
level的记忆技巧:lev 提高 + el 地点 → 举到同一高度 → 平的。
level, flat这两个词都有“平的”“平坦的”意思。其区别在于:
1.flat指表面水平或类似水平,即没有显著的起伏与倾斜。
2.level指“平均”,即没有明显的弯曲与凸凹,但不一定水平。例如:
This road is level until you get near the hill.
这条路很平,你可直达附近小山。
热心网友 时间:2022-05-03 12:56
level热心网友 时间:2022-05-03 14:31
付费内容限时免费查看回答你好,很荣幸为您解答。意思是:生日的意义在于你在乎的人陪你一起过。
热心网友 时间:2022-05-03 16:22
跑跑的L就是等级了