【leveldb】arnaメモリ構造
2578 ワード
本論文では、arnaメモリ管理の設計と実現を紹介します.
arnaはleveldbの中の非常に簡単なメモリプールです.以下で詳しく紹介します.
1データ構造
arnaデータ構造は以下の通りです.ここでblocks_作成したすべてのブロックが保存されています.blocksmemoryblock申請の全空間を保存します.alloc_ptr_alloc_とbytes_remaning_それぞれ現在のブロックのメモリには、開始アドレスと利用可能な空間サイズが割り当てられています.
3メモリを解放する
arnaはleveldbの中の非常に簡単なメモリプールです.以下で詳しく紹介します.
1データ構造
arnaデータ構造は以下の通りです.ここでblocks_作成したすべてのブロックが保存されています.blocksmemoryblock申請の全空間を保存します.alloc_ptr_alloc_とbytes_remaning_それぞれ現在のブロックのメモリには、開始アドレスと利用可能な空間サイズが割り当てられています.
// Allocation state
char* alloc_ptr_;
size_t alloc_bytes_remaining_;
// Array of new[] allocated memory blocks
std::vector blocks_;
// Bytes of memory in blocks allocated so far
size_t blocks_memory_;
2メモリ割り当て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);
}
// Allocate memory with the normal alignment guarantees provided by malloc
char* AllocateAligned(size_t 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::AllocateNewBlock(size_t block_bytes) {
char* result = new char[block_bytes];
blocks_memory_ += block_bytes;
blocks_.push_back(result);
return result;
}
メモリ割り当てはAllocate法により完了し、AllocateAlignedを使用してサイズ揃えのメモリを得ることができます.Allocate方法はまずalloc_によります.bytes_remaning_現在のblockの空き領域が十分かどうかを判断し、十分であれば直接現在のblockに申請する.足りない時、必要な空間の大きさを判断して、1/4より大きいblocksizeであれば、単独のblockとして申請します.1/4以下のblocksizeの場合、新しいblockを申請して、新しいblockからメモリを割り当てます.blockとして単独で申請する場合、alloc_ptr_alloc_とbytes_remaning_指すblockは変化していません.つまり、現在のblockの空き容量はまだ使えます.だから、メモリの無駄を減らすことができます.blockごとに、最大1/4を超えないblocksizeのメモリは浪費されます.このblocksizeは4096に設定されています.3メモリを解放する
Arena::Arena() {
blocks_memory_ = 0;
alloc_ptr_ = NULL; // First allocation will allocate a block
alloc_bytes_remaining_ = 0;
}
Arena::~Arena() {
for (size_t i = 0; i < blocks_.size(); i++) {
delete[] blocks_[i];
}
}
メモリはarnaオブジェクトが破壊された時だけ、統一的に解放されます.だからAreenaメモリは成長するしかないです.