標籤:windows 記憶體池
.h檔案
/**********************說明************************** 這是MPool記憶體池的實現,他具有如下特性:* 1. 池中的記憶體塊是大小是相同的* 2. 由宏定義_MP_NO_SERIALIZE決定是否需要多線程同步* 3. 他利用windows的堆記憶體API進行記憶體配置* 4. 他不能替換crt的malloc和free* 5. 他不是一個通用型的記憶體池* 6. 適用於特定的應用環境(高頻率的申請釋放記憶體,如網路伺服器),應用環境影響池中記憶體塊的大小,以及是否需要處理多線程同步** 編寫這樣一個記憶體池基於這幾點原因* 1. 減少記憶體片段(每次分配等長的記憶體塊有利於減少記憶體片段,記憶體塊的大小還要考慮記憶體對齊)* 2. 提高記憶體配置效率(非序列化的記憶體配置可以顯著提高效率)* 3. 網路上很多通用型記憶體池的做法,本人認為通用型的記憶體池就應該是作業系統本身的記憶體管理API, 在ring3層做通用記憶體池沒有意義,甚至可能起到反效果。這種情況最簡單的解決問題的辦法是增加實體記憶體的容量。 只有針對特定的應用環境編寫的記憶體池才是有意義的。*/#ifndef MPOOL_H#define MPOOL_H#include <Windows.h>#include <vector>using std::vector;class MPool{public: MPool(size_t block_size); ~MPool(); void *MPAlloc(); void MPFree(void *p);private: MPool(const MPool&); MPool& operator=(const MPool&);private: RTL_CRITICAL_SECTION *m_pool_lock; vector<void*> m_block_list; size_t m_block_size; size_t m_total_size; size_t m_block_count; size_t m_reserve_count; HANDLE m_heap; DWORD m_heap_option;};#endif
.cpp檔案
#include "mpool.h"#ifdef _MP_NO_SERIALIZE#define MPLOCK() #define MPUNLOCK() #else#define MP_LOCK() EnterCriticalSection(m_pool_lock);#define MP_UNLOCK() LeaveCriticalSection(m_pool_lock);#endifMPool::MPool( size_t block_size ){ m_block_size = block_size; size_t m = m_block_size % 8; if(m != 0) { m_block_size += (8-m); } _SYSTEM_INFO info; memset(&info,0,sizeof(_SYSTEM_INFO)); GetSystemInfo(&info); m_heap_option = 0;#ifdef _MP_NO_SERIALIZE m_heap_option = HEAP_NO_SERIALIZE;#else m_pool_lock = new RTL_CRITICAL_SECTION; InitializeCriticalSectionAndSpinCount(m_pool_lock,4000);#endif m_heap = HeapCreate(m_heap_option,info.dwPageSize,0); m_block_list.reserve(1024);}MPool::~MPool(){ while(!m_block_list.empty()) { HeapFree(m_heap,m_heap_option,m_block_list.back()); m_block_list.pop_back(); }#ifndef _MP_NO_SERIALIZE DeleteCriticalSection(m_pool_lock); delete m_pool_lock;#endif}_inline void * MPool::MPAlloc(){ void *ret; MP_LOCK(); if(!m_block_list.empty()) { ret = m_block_list.back(); m_block_list.pop_back(); } else { ret = HeapAlloc(m_heap,m_heap_option,m_block_size); } MP_UNLOCK(); return ret; }_inline void MPool::MPFree( void *p ){ if(p) { MP_LOCK(); m_block_list.push_back(p); MP_UNLOCK(); }}