記憶體池的原理及實現

2021-08-27 15:23:57 字數 2545 閱讀 7587

在軟體開發中,有些物件使用非常頻繁,那麼我們可以預先在堆中例項化一些物件,我們把維護這些物件的結構叫「記憶體池」。在需要用的時候,直接從記憶體池中拿,而不用從新例項化,在要銷毀的時候,不是直接free/delete,而是返還給記憶體池。

把那些常用的物件存在記憶體池中,就不用頻繁的分配/**記憶體,可以相對減少記憶體碎片,更重要的是例項化這樣的物件更快,**也更快。當記憶體池中的物件不夠用的時候就擴容。

我的記憶體池實現如下:

#pragma once#include 

template

struct

proxyt

t data;

proxyt*next;

};template

class

memorypool

assert(next!=null);

proxyt

* cur=next;

next=next->next;

return

cur;

}static

void delete(void*ptr)

#ifdef canfree

static

void

clear()

next=null;

}#endif

private

:

static

void alloc(size_t size=16

)

#else

proxyt

* memory=(proxyt*)malloc(size*sizeof(proxyt));

proxyt

* tmpproxy=new (memory) proxyt();

next=tmpproxy;

for (size_t i=1;i)

#endif

} }

static proxyt*next;

memorypool

(); memorypool

(const memorypool&);

};template

proxyt* memorypool::next=null;

#define newanddelete(classname) \

static

void* operator

new(size_t size) \

\static

void

operator delete(void*ptr) \

測試**如下:

#include "

stdafx.h

"#define canfree#include

"memorypool.h

"structa;

int _tmain(int argc, _tchar*argv)

for(int i=0;i)

for(int i=vect.size()-1;i>=0;i--)

vect.clear();

memorypool

::clear();

}system(

"pause");

return0;

}

執行結果如下圖:

不到100行**,有兩個public方法new和delete;還有乙個clear方法,這個方法的存在取決於是否定義了巨集canfree,如果定義了這個巨集,那麼物件是乙個個的例項化,在呼叫clear的時候可以乙個個的**,如果沒有定義,那麼是一次分配一塊較大的記憶體,然後在這塊記憶體上例項化多個物件,但沒有實現**這塊記憶體的方法,如果要**這樣的大塊記憶體塊,就必須將這些記憶體塊的首位址存起來,我這裡沒有存起來,而且還要標記物件是否使用,那麼proxy還要加乙個字段表示是否使用,在**的時候還要判斷所有物件是否沒有使用,只有都沒使用才能**,妹的,為了**弄得這麼麻煩,話說你為什麼要**記憶體池呢,於是就沒有實現**的方法。整個記憶體池其實就是乙個單鏈表,表頭指向第乙個沒有使用節點,我們可以把這個單鏈表想象成一段鏈條,呼叫方法new就是從鏈條的一端(單鏈表表頭)取走一節點,呼叫方法delete就是在鏈條的一端(單鏈表表頭)前面插入乙個節點,新插入的節點就是鍊錶的表頭,這樣new和delete的時間複雜度都是o(1),那叫乙個快。

所有要使用記憶體池的物件,只需要在這個物件中引入巨集newanddelete,這個巨集其實就是重寫物件的new和delete方法,讓物件的建立和**都通過記憶體池來實現,所有用記憶體池實現的物件使用起來和別的物件基本上是一樣,唯一的乙個問題就是記憶體池物件物件不是執行緒安全的,在多執行緒程式設計中,建立乙個物件時必須枷鎖。如果在new和delete的實現中都加個鎖,我又覺得他太影響效能,畢竟很多時候是不需要枷鎖,有些物件可能有不用於多執行緒,對於這個問題,求高手指點!

C 記憶體池的簡單原理及實現

c 程式預設的記憶體管理 new,delete,malloc,free 會頻繁地在堆上分配和釋放記憶體,導致效能的損失,產生大量的記憶體碎片,降低記憶體的利用率。預設的記憶體管理因為被設計的比較通用,所以在效能上並不能做到極致。因此,很多時候需要根據業務需求設計專用記憶體管理器,便於針對特定資料結構...

執行緒池原理及python實現

為什麼需要執行緒池 目前的大多數網路伺服器,包括web伺服器 email伺服器以及資料庫伺服器等都具有乙個共同點,就是單位時間內必須處理數目巨大的連線請求,但處理時間卻相對較短。傳統多執行緒方案中我們採用的伺服器模型則是一旦接受到請求之後,即建立乙個新的執行緒,由該執行緒執行任務。任務執行完畢後,執...

執行緒池原理及py實現

目前的大多數網路伺服器,包括web伺服器 email伺服器以及資料庫伺服器等都具有乙個共同點,就是單位時間內必須處理數目巨大的 連線請求,但處理時間卻相對較短。傳統多執行緒方案中我們採用的伺服器模型則是一旦接受到請求之後,即建立乙個新的執行緒,由該執行緒執行任務。任務執行完畢後,線 程退出,這就是是...