這是我翻譯的文章,來自 Code Project,
原文作者: DanDanger2000.
原文連結: http://www.codeproject.com/cpp/MemoryPool.asp
C++ 記憶體池
l 下載樣本工程 – 105Kb
l 下載原始碼 – 17.3Kb
目錄 l 引言 l 它怎樣工作 l 樣本 l 使用這些代碼 l 好處 l 關於代碼 l ToDo l 曆史 引言 C/C++ 的記憶體配置 ( 通過 malloc 或 new) 可能需要花費很多時。 更糟糕的是,隨著時間的流逝,記憶體 (memory) 將形成片段,所以一個應用程式的運行會越來越慢當它運行了很長時間和 / 或執行了很多的記憶體配置 ( 釋放 ) 操作的時候。特別是,你經常申請很小的一塊記憶體,堆 (heap) 會變成片段的。 解決方案:你自己的記憶體池 一個 ( 可能的 ) 解決方案是記憶體池 (Memory Pool) 。 在啟動的時候,一個 ” 記憶體池 ”(Memory Pool) 分配一塊很大的記憶體,並將會將這個大塊 (block) 分成較小的塊 (smaller chunks) 。每次你從記憶體池申請記憶體空間時,它會從先前已經分配的塊 (chunks) 中得到, 而不是從作業系統。最大的優勢在於: l 非常少 ( 幾沒有 ) 堆片段 l 比通常的記憶體申請 / 釋放 ( 比如通過 malloc , new 等 ) 的方式快 另外,你可以得到以下好處: l 檢查任何一個指標是否在記憶體池裡 l 寫一個 ” 堆轉儲 ( Heap-Dump )” 到你的硬碟 ( 對事後的調試非常有用 ) l 某種 ” 記憶體流失檢測 ( memory-leak detection )” :當你沒有釋放所有以前分配的記憶體時,記憶體池 (Memory Pool) 會拋出一個斷言 ( assertion ). 它怎樣工作 讓我們看一看記憶體池 (Memory Pool) 的 UML 模式圖: 這個模式圖只顯示了類 CMemoryPool 的一小部分,參看由 Doxygen產生的文檔以得到詳細的類描述。 一個關於記憶體塊(MemoryChunks)的單詞 你應該從模式圖中看到, 記憶體池 (Memory Pool) 管理了一個指向結構體 SMemoryChunk ( m_ptrFirstChunk , m_ptrLastChunk , and m_ptrCursorChunk ) 的指標。這些塊 (chunks) 建立一個記憶體塊 (memory chunks) 的鏈表。各自指向鏈表中的下一個塊 (chunk) 。當從作業系統分配到一塊記憶體時,它將完全的被 SMemoryChunk s 管理。讓我們近一點看看一個塊 (chunk) 。
typedef struct SMemoryChunk
{
TByte *Data ; // The actual Data
std::size_t DataSize ; // Size of the "Data"-Block
std::size_t UsedSize ; // actual used Size
bool IsAllocationChunk ; // true, when this MemoryChunks
// Points to a "Data"-Block
// which can be deallocated via "free()"
SMemoryChunk *Next ; // Pointer to the Next MemoryChunk
// in the List (may be NULL)
} SmemoryChunk;
每個塊(chunk)持有一個指標,指標指向: l 一小塊記憶體 ( Data ) , l 從塊 (chunk) 開始的可用記憶體的總大小 ( DataSize ) , l 實際使用的大小 ( UsedSize ) , l 以及一個指向鏈表中下一個塊 (chunk) 的指標。 第一步:預申請記憶體(pre-allocating the memory) 當你調用 CmemoryPool 的建構函式,記憶體池 (Memory Pool) 將從作業系統申請它的第一塊 ( 大的 ) 記憶體塊 (memory-chunk) /*Constructor
******************/
CMemoryPool::CMemoryPool( const std::size_t & sInitialMemoryPoolSize,
const std::size_t & sMemoryChunkSize,
const std::size_t & sMinimalMemorySizeToAllocate,
bool bSetMemoryData)
{
m_ptrFirstChunk = NULL ;
m_ptrLastChunk =