對於乙個高效能的伺服器程式來說,記憶體的使用非常重要。c++提供new/delete來管理記憶體的申請和釋放,但是對於小物件來說,直接使用new/delete代價比較大,要付出額外的空間和時間,價效比不高。另外,也需要避免多次申請和釋放引起的記憶體碎片。一旦碎片到達一定程度,即使剩餘記憶體足夠用,但由於缺乏足夠的連續的空閒空間,導致記憶體不夠用的假象。
c++ stl為避免記憶體碎片實現了乙個複雜的記憶體池,leveldb則沒有那麼複雜,只是實現了乙個「一次性」記憶體池arena。leveldb並不是所有地方都使用了該記憶體池,主要是memtable使用,主要是用於臨時存放使用者的更新資料,由於更小的資料可能較小,所以這裡使用記憶體池就很合適。
為避免小物件的頻繁分配,需要減少對new的呼叫,最簡單的做法就是申請大塊的記憶體,多次分給客戶。leveldb使用乙個vector來儲存所有記憶體分配記錄表,預設每次申請4k的記憶體,記錄下剩餘指標和剩餘記憶體位元組數。每當有新的申請,如果當前剩餘的位元組能滿足需求,則直接返回給使用者,否則,對於超過1k的申請,直接new返回,小於1k的申請,則申請乙個新的4k塊,從中分配一部分給使用者。
但這樣存在乙個問題當前塊剩餘部分就浪費了,改進的方法,針對每個block都記錄剩餘位元組數,但如此需要遍歷查詢合適的block,要付出一定效能的代價。谷歌的做法是浪費就浪費吧。至於釋放就需要釋放整個記憶體池來釋放所佔的記憶體,這個和leveldb的需求有關,memtable不需要釋放單次記憶體,flush到硬碟後整個memtable銷毀。
arena.h
#ifndef storage_leveldb_util_arena_h_#define storage_leveldb_util_arena_h_#include
#include
#include
#include
#include
namespace
leveldb
private
:
char*allocatefallback(size_t bytes);
char*allocatenewblock(size_t block_bytes);
char*alloc_ptr_;
size_t alloc_bytes_remaining_;
std::vector
block_;
std::atomic
memory_usage_;
};inline
char*arena::allocate(size_t bytes)
return
allocatefallback(bytes);}}
#endif
arena.cc
#include "arena.h
"namespace
leveldb
arena::~arena()
}char*arena::allocatefallback(size_t bytes)
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)
else
assert((reinterpret_cast
(result) & (align - 1)) == 0
);
return
result;
}char*arena::allocatenewblock(size_t block_bytes)
}
參考部落格:
《原始碼閱讀》原始碼閱讀技巧,原始碼閱讀工具
檢視某個類的完整繼承關係 選中類的名稱,然後按f4 quick type hierarchy quick type hierarchy可以顯示出類的繼承結構,包括它的父類和子類 supertype hierarchy supertype hierarchy可以顯示出類的繼承和實現結構,包括它的父類和...
Cartographer原始碼篇 原始碼分析 1
在安裝編譯cartographer 1.0.0的時候,我們可以看到 主要包括cartorgarpher ros cartographer ceres sover三個部分。其中,ceres solver用於非線性優化,求解最小二乘問題 cartographer ros為ros平台的封裝,獲取感測器資料...
python原始碼剖析 Python原始碼剖析
第頁共 頁python 原始碼剖析 物件機制 1.物件 在python 的世界中,一切都是物件,乙個整數是乙個物件,乙個字串也是 乙個物件,更為奇妙的是,型別也是乙個物件,整數型別是乙個物件,字串類 型也是乙個物件。從 年guido 在那個聖誕節揭開 python 世界的大幕開始,一直到現在,pyt...