我有一個Visual Studio 2008 C++應用程序,我正在使用標準容器的自定義分配器,以使它們的內存來自內存映射文件而不是堆。這個分配器用於4種不同的用例:關於改進分配器算法實現的建議
- 104字節的固定尺寸的結構
std::vector< SomeType, MyAllocator<SomeType> > foo;
- 200字節的固定尺寸結構
- 304字節的固定尺寸結構
- n字節串
std::basic_string< char, std::char_traits<char>, MyAllocator<char> > strn;
我需要能夠爲其中每一個分配大致32MB的總計。
分配程序使用指向分配大小的指針跟蹤內存使用情況。每個超級塊代表4MB的內存。
有一個std::vector<SuperBlock>
這些萬一一個超級塊沒有足夠的空間。
用於分配的算法是這樣的:
- 對於每個超級塊:是否有空間在超級塊的結束?把分配放在那裏。 (快)
- 如果不是,則在每個超級塊內搜索足夠大小的空白空間並將其分配到那裏。 (慢)
- 還沒什麼?分配另一個超級塊,並將分配放在新超級塊的開始處。
不幸的是,步驟2在一段時間後會變得非常慢。隨着對象的拷貝和臨時變量的銷燬,我得到了很多碎片。這會導致在內存結構中進行大量的深層搜索。由於我的內存數量有限(請參閱下面的註釋),因此存在碎片問題。
有人可以提出改進此算法以加快此過程嗎?我是否需要兩個獨立的算法(1個用於固定大小的分配,另一個用於字符串分配器)?
注意:對於那些需要一個原因:我在Windows Mobile中使用此算法,其中有一個32MB的進程槽限制堆。所以,通常std::allocator
不會削減它。我需要將分配放在1GB的大內存區域中,以獲得足夠的空間,這就是它的功能。
將固定大小和可變大小相結合的好主意。我剛剛實現了這一點,確實非常快。謝謝。 – PaulH 2011-05-17 19:48:06
您應該閱讀Matthieu M.的答案,它更加完整和相當出色,並解決了您在部署自己的分配器時遇到的大量問題。 – 2011-05-17 21:44:09