(转载)简单linux C++内存池
生活随笔
收集整理的這篇文章主要介紹了
(转载)简单linux C++内存池
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
C++代碼
?
描述:以STL-vector為數據存儲單元,實現簡單的內存池功能。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | 在學習內存池的過程中可謂云游太虛。一般都是針對標準內存池再次實現。大部分以鏈表的形式討論。誠然最正宗也最準確,但是相對比較晦澀,本文是針對剛剛接觸內存池的同學寫的。大大減少了對內存池整體認識的難度。 ?? 內存池: 如果程序中涉及頻繁申請釋放內存,并且每次使用的內存并不是很大,這時候應該考慮內存池。 內存池可以有有效的避免內存碎片的產生。 內存池的框架: class MemPool{ public: MemPool(){初始化分配N個小的內存塊} ~MemPool(){真正刪除整個分配了的內存空間} void* getmem(){獲取內存(塊)} void freemem(){釋放內存到內存池中,這里并不是真正的釋放掉內存,只是回收再利用;} private: struct LinkBlock * p;//把很多小內存塊關聯起來的結構,大部分寫成鏈表的形式 mem_block* m_block;//一個小的內存塊。 }; 工作機制: 事先分配出一大塊內存,再把這一大塊分成很多小塊。當程序中需要申請內存時就拿出一小塊來用。用完了就把這一小塊放回大塊中(注意:這個小塊內存并沒釋放掉!),只要不是一下用掉了所有一大塊內存,無論多少次申請內存都是重復利用這些小的內存塊。知道程序結束真正釋放掉整片內存。 所以用內存池可以把大量的內存申請控制在可計算的范圍內。內存碎片少。比如:如果用系統的new或者malloc申請10000次內存,可能要10000的小的內存空間,但是使用內存池只需申請100塊空間,循環利用100次而已。作用顯而易見! ?? 為了讓程序簡單明了使用STL標準庫的vector來充當小內存塊的管理器。 vector<char*> vec; 這樣每次申請的是vec的一個迭代器的空間。 ?? 代碼非原創,稍稍做了改動而已。 ======================================================================== MemPool.h ?? #ifndef _MEM_POOL_H??? #define _MEM_POOL_H???? #include <vector>??? #include <iostream>??? using namespace std;?? ?? /*? ????在內存池中分配固定大小的內存塊?? ????目的是加速內存分配速度,并且減少因重復分配相同?? */?? ?? class CMemPool?? {?? public:?? ?????? ????//創建大小為blockSize的內存塊,內存池數目為預分配的數目preAlloc??? ????CMemPool(int blockSize, int preAlloc = 0, int maxAlloc = 0);?? ?????? ????~CMemPool();?? ?????? ????//獲取一個內存塊。如果內存池中沒有足夠的內存塊,則會自動分配新的內存塊??? ????//如果分配的內存塊數目達到了最大值,則會返回一個異常??? ????void* Get();?? ?????? ????//釋放當前內存塊,將其插入內存池??? ????void Release(void* ptr);?? ?????? ????//返回內存塊大小??? ????int BlockSize() const;?? ?????? ????//返回內存池中內存塊數目??? ????int Allocated() const;?? ?????? ????//返回內存池中可用的內存塊數目??? ????int Available() const;?? ?????? private:?? ????CMemPool();?? ????CMemPool(const CMemPool&);?? ????CMemPool& operator = (const CMemPool&);?? ?????? ????enum?? ????{?? ????????BLOCK_RESERVE = 128?? ????};?? ?????? ????typedef std::vector<char*> BlockVec;?? ?????? ????int m_blockSize;?? ????int???????? m_maxAlloc;?? ????int???????? m_allocated;?? ????BlockVec??? m_blocks;?? };?? ?? inline int CMemPool::BlockSize() const?? {?? ????return m_blockSize;?? }?? ?? inline int CMemPool::Allocated() const?? {?? ????return m_allocated;?? }?? ?? inline int CMemPool::Available() const?? {?? ????return (int) m_blocks.size();?? }?? #endif?? ?? ========================================================= MemPool.cpp ?? ?? #include "MemPool.h"??? CMemPool::CMemPool(int blockSize, int preAlloc, int maxAlloc):?? m_blockSize(blockSize),?? m_maxAlloc(maxAlloc),?? m_allocated(preAlloc)?? {?? ????if ( preAlloc < 0 || maxAlloc == 0 || maxAlloc < preAlloc )?? ????{?? ????????cout<<"CMemPool::CMemPool parameter error."<<endl;?? ????}?? ?????? ????int r = BLOCK_RESERVE;?? ????if (preAlloc > r)?? ????????r = preAlloc;?? ????if (maxAlloc > 0 && maxAlloc < r)?? ????????r = maxAlloc;?? ????m_blocks.reserve(r);?? ????for (int i = 0; i < preAlloc; ++i)?? ????{?? ????????m_blocks.push_back(new char[m_blockSize]);?? ????}?? }????? CMemPool::~CMemPool()?? {?? ????for (BlockVec::iterator it = m_blocks.begin(); it != m_blocks.end(); ++it)?? ????{?? ????????delete [] *it;?? ????}?? }?? ?? void* CMemPool::Get()?? {???? ?????? ????if (m_blocks.empty())?? ????{?? ????????if (m_maxAlloc == 0 || m_allocated < m_maxAlloc)?? ????????{?? ????????????++m_allocated;?? ????????????return new char[m_blockSize];?? ????????}?? ????????else?? ????????{?? ????????????cout<<"CMemPool::get CMemPool exhausted."<<endl;?? ????????????return (void *)NULL;?? ????????}?? ????}?? ????else?? ????{?? ????????char* ptr = m_blocks.back();?? ????????m_blocks.pop_back();?? ????????return ptr;?? ????}?? }?? ?? ?? void CMemPool::Release(void* ptr)?? {??? ????memset(ptr,0,sizeof(char)*m_blockSize);//內存回收回來以后并沒銷毀,原數據仍在,所以應該清空 ????m_blocks.push_back(reinterpret_cast<char*>(ptr));?? }??? ?? ========= main.h ?? #include "stdafx.h" #include "MemPool.h" #include <string.h> int main(int argc, char* argv[]) { CMemPool *m_cache =new CMemPool(50,0,10); ?? char * src_date="abcdefg"; char *p1=(char*)(m_cache->Get()); char *p2=(char*)(m_cache->Get()); int *p3=(int*)(m_cache->Get()); strcpy(p1,src_date); strcpy(p2,src_date); p3[0]=9;p3[1]=25; ?? m_cache->Release(p1); m_cache->Release(p2); m_cache->Release(p3); ?? //把MemPool.cpp中void CMemPool::Release(void* ptr) 的 //memset(ptr,0,sizeof(char)*m_blockSize);注釋掉可以驗證每次內存回收以后是重復利用而非銷毀 cout<<*(int*)(m_cache->Get())<<endl; cout<<(char*)(m_cache->Get())<<endl; cout<<(char*)(m_cache->Get())<<endl; delete m_cache; ????return 0; } ?? 完畢! ?? 當然這只是探究內存池而已,更高級的比如線程安全,內存擴容,模板等等,仍需解決。 但是相信想初窺內存池門徑應該還是有幫助的! |
總結
以上是生活随笔為你收集整理的(转载)简单linux C++内存池的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (转载)c++内存池实现 .
- 下一篇: Win下PHP环境Eclipse PDT