1.記憶體池的引入
實際運用當中,如果我們需要申請一塊空間,我們一般都會new一塊空間(在c語言裡會用到malloc),我們知道他們兩個的共同點就是在堆上申請空間,堆上的空間會比棧上的大一些(在windows的vs環境下,棧的預設大小是1mb,但是可以自己調整
),所以我們可以自己去申請自己需要的大小(當然也是有一定的限制)。如果我們頻繁的去申請釋放空間,就會形成各種各樣的記憶體碎片,這樣就造成了記憶體的浪費。如果我們可以將自己需要的小的空間自己儲存起來(不交給作業系統管理),下次需要的時候,從自己儲存的記憶體池子裡邊取,這樣不僅快,還不會造成太大的浪費。
關於記憶體碎片:
記憶體碎片包括外部碎片和內部碎片,外部碎片就是,這個小的記憶體塊的大小很長一段時間都沒有找到對記憶體的需求小於它的作業;內部碎片就是給定乙個記憶體塊的大小,作業進入記憶體僅僅只需要一部分,剩下的就浪費了,浪費的部分就是內部碎片。
2.記憶體池的實現機制
(1)申請空間:
每次申請空間時,我們都必須優先使用上一次釋放的空間,如果上一次沒有釋放,那麼則
在記憶體池中找一塊空間進行分配;如果上一次有進行釋放,則使用上一次釋放的空間,將_lastdelete(
維護最後一次釋放空間的指標
)指向倒數第二次釋放的空間。
註明:對於釋放的空間,我們就可以合理使用,我們可以將最後一次釋放的空間裡儲存倒數第二次釋放的空間的位址,這樣就涉及到乙個問題:
如果乙個物件的大小不足以儲存乙個位址(指標型別在32位系統下是4位元組,在64位系統下是8位元組),如果物件的大小大於指標的大小,直接分配物件的大小(釋放之後,裡邊仍然可以儲存上一次釋放的記憶體的位置);如果物件的大小不足以指標的大小,那麼就浪費一點空間,給它分配乙個指標的大小。
圖示:
(2)釋放空間:
釋放空間就是將當前不要的記憶體還給記憶體池,在這裡也就是讓_lastdelete指向這塊要申請的空間,這塊空間裡儲存原來
_lastdelete的值。但是,別忘了最重要的一點:
delete的實現原理:先呼叫析構函式,然後再還空間。
在我們簡單的記憶體池的delete函式中,對於內建型別析構不析構都是無所謂的,但是自定義型別(比如string)必須顯式呼叫析構函式,然後再還空間。
我們簡易的記憶體池---固定大小,在這樣的一種情況下特別佔優勢:
重複的申請和釋放,這樣的記憶體池的速度是快於系統的new和delete。當多次的申請和釋放,我們都是會使用之前釋放的空間,就不用去和作業系統打交道。
3.實現**
#includeusing namespace std;
#include#includetemplateclass objectpool
~blocknode()
};protected:
size_t _countin;//當前結點在用的計數
blocknode* _first;
blocknode* _last;
size_t _maxnum;
static size_t _itemsize;//單個物件的大小
t* _lastdelete;
public:
objectpool(size_t initnum = 32,size_t maxnum = 10000)
~objectpool()
_first = _last = null;
_countin = 0;
}static size_t getitemsize()
}void allocate()
t* new()
//從記憶體塊裡進行申請
//所有結點的記憶體塊都沒有可以使用的,則重新開闢新的空間
if(_last->_objnum == _countin)//最後乙個結點的記憶體也被用完了
t* mem = (t*)((char*)(_last->_memory) + _countin * _itemsize);
_countin++;
return new(mem) t;
}void delete(t* ptr)
*(t**) ptr = _lastdelete;
_lastdelete = ptr;
}};templatesize_t objectpool::_itemsize = objectpool::getitemsize();
關於申請大小不固定記憶體的記憶體池實現,在之後的文章將與大家分享。 簡易記憶體池的實現
參考 一書中的條款10 如果寫了operator new就要同時寫operator delete 寫了乙個簡易的記憶體池,說白了就是事先分配一塊記憶體空間作為記憶體池,每次new物件的時候,直接從這裡取記憶體,delete的時候將記憶體 到記憶體池中,很簡單,廢話就不說了,直接看 include s...
簡易記憶體池(物件池)的實現
pragma once include include include 物件池的實現 針對於乙個知道型別的物件 我們通過物件池 來比較普通向記憶體中申請空間 和我們直接向我們的記憶體池中申請空間的效能對比 template class t,size t initnum 10000 設定記憶體池中取出...
簡易記憶體池
include new 1.開闢記憶體 2.初始化 delete 1.釋放資源 2.釋放記憶體 new1.開闢記憶體 operator new 系統 2.呼叫建構函式 delete 1.呼叫析構函式 2.釋放物件的記憶體 operator delete 系統 自主的記憶體管理機制 通過對new,de...