github:記憶體池的存在主要就是減少呼叫emai: [email protected]
華為雲社群:
leveldb:
malloc
或者new
的次數,減少記憶體分配所帶來的系統開銷,提公升效能。
leveldb 中的記憶體池是由類arena
實現的。arena
先向系統申請一塊大的記憶體,當其他元件需要申請記憶體時,arena
先將已有的記憶體塊分配給元件,如果不夠用則再申請一塊大的記憶體。當記憶體池物件析構時,分配的記憶體均被釋放,這保證了記憶體不會洩漏。
申請記憶體和分配記憶體的區別:
// 指向當前記憶體塊未分配記憶體的起始位址的指標
char* alloc_ptr_;
// 記錄當前記憶體塊未分配記憶體的大小
size_t alloc_bytes_remaining_;
// 每個記憶體塊的位址都儲存在 vector 中
std::vectorblocks_;
// 原子變數:記錄當前物件的記憶體總量
std::atomicmemory_usage_;
如圖所示,arena
的成員變數blocks_
儲存若干個指標,每個指標指向一塊記憶體。alloc_ptr_
指向當前記憶體塊未分配記憶體的起始位址,alloc_bytes_remaining_
為當前記憶體塊未分配記憶體的大小。
static const int kblocksize = 4096;
arena
以記憶體塊為單位來管理記憶體,每個記憶體塊的大小kblocksize
為 4096 kb。
arena::arena()
: alloc_ptr_(nullptr), alloc_bytes_remaining_(0), memory_usage_(0) {}
arena::~arena()
}
建構函式初始化所有的成員變數,保證不會使用未初始化的變數。
析構函式釋放blocks_
中每個指標指向的記憶體塊。
arena
提供了 3 個public
函式來簡化記憶體分配。
arena
的記憶體分配策略有三種,當申請bytes
大小的記憶體時:
inline char* arena::allocate(size_t bytes)
// 申請的記憶體大於當前記憶體塊剩餘的記憶體,使用 allocatefallback 函式重新申請記憶體
return allocatefallback(bytes);
}
allocate
函式分配bytes
大小的記憶體空間,返回指向所分配記憶體的指標。
char* arena::allocatealigned(size_t bytes) else
// 保證分配的記憶體起始位址是位元組對齊的
assert((reinterpret_cast(result) & (align - 1)) == 0);
return result;
}
allocatealigned
函式分配bytes
大小的記憶體空間,且起始位址位元組對齊,返回指向所分配記憶體的指標。
size_t memoryusage() const
memoryusage
函式返回當前分配給arena
物件的所有記憶體空間大小和所有指向記憶體塊的指標大小之和。
接上節中的arena
的記憶體分配策略,當申請bytes
大小的記憶體時:
char* arena::allocatefallback(size_t bytes)
// 呼叫 allocatenewblock 申請一塊大小為 kblocksize 的新記憶體塊
alloc_ptr_ = allocatenewblock(kblocksize);
alloc_bytes_remaining_ = kblocksize;
// 在新申請的記憶體塊中分配 bytes 大小的記憶體
char* result = alloc_ptr_;
alloc_ptr_ += bytes;
alloc_bytes_remaining_ -= bytes;
return result;
}
當申請的記憶體大於當前記憶體塊剩餘記憶體時,allocatefallback
函式會被呼叫,用來按照後兩種分配策略分配記憶體。
這兩種分配策略可以進一步減少記憶體分配的次數,但同時每塊最後 \(\frac\) 的空間有可能會被浪費。
char* arena::allocatenewblock(size_t block_bytes)
allocatenewblock
函式申請乙個大小為block_bytes
的記憶體塊。
當向arena
申請bytes
大小的記憶體時:
LevelDB原始碼剖析之Memtable 1
memtable是leveldb很重要的一塊,leveldb的核心之一。我們肯定關注kv資料在memtable中是如何組織的,秘密在skip list中。在leveldb中,所有記憶體中的kv資料都儲存在memtable中,物理disk則儲存在sstable中。在系統執行過程中,如果memtable...
leveldb原始碼分析之Arena
arena 是 leveldb 專案裡面使用的輕量級的記憶體池物件,leveldb 用這個物件來管理記憶體的分配,簡化了 new 和 delete 的呼叫,我們也可以從這個輕量級的記憶體池物件學習 google 大神工程師是如何管理記憶體的。arena 記憶體管理模型 arena 使用下面幾個成員變...
leveldb原始碼分析之SSTable檔案例項講解
sstable檔案是memtable 資料到一定閾值寫入檔案形成的,由於記憶體容量總是有限的,將一定量資料寫入磁碟可以存放更多資料,所以leveldb相比redis能存放更多資料。既然資料持久化到磁碟,那麼還有必然涉及到從磁碟中查詢資料,從磁碟中查詢資料與從記憶體中查詢資料的效率是不一樣的,所以ss...