記憶體池的設計和實現總結(一)

2022-09-02 12:30:14 字數 4752 閱讀 3417

c/c++下記憶體管理是讓幾乎每乙個程式設計師頭疼的問題,分配足夠的記憶體、追蹤記憶體的分配、在不需要的時候釋放記憶體——這個任務相當複雜。而直接使用系統呼叫malloc/free、new/delete進行記憶體分配和釋放,有以下弊端:

呼叫malloc/new,系統需要根據「最先匹配」、「最優匹配」或其他演算法在記憶體空閒塊表中查詢一塊空閒記憶體,呼叫free/delete,系統可能需要合併空閒記憶體塊,這些會產生額外開銷

頻繁使用時會產生大量記憶體碎片,從而降低程式執行效率

容易造成記憶體洩漏

記憶體池則是在真正使用記憶體之前,先申請分配一定數量的、大小相等(一般情況下)的記憶體塊留作備用。當有新的記憶體需求時,就從記憶體池中分出一部分記憶體塊,若記憶體塊不夠再繼續申請新的記憶體。這樣做的乙個顯著優點是,使得記憶體分配效率得到提公升。

本章先實現乙個簡單的記憶體池(csinglememorypools)。該記憶體池提供一定數量、大小相等的記憶體塊。該例項中,csinglememorypools中的m_pmemoryfreelist負責對空閒記憶體塊進行管理,每個記憶體塊以_memoryblock類進行管理,其中首部有4個位元組的指標塊位址 + 4個位元組的list表首位址 + 4位驗證碼,然後才是分配的記憶體。

1

#pragma once 23

//開發乙個簡單的記憶體池,用於記憶體管理。

45 #include 6 #include 7 #include 8 #include "

threadlock.h"9

10#define max_memoryhead_size 12 //

4個位元組的指標塊位址 + 4個位元組的list表首位址 + 4位驗證碼

11#define magic_code 0xffffff //

驗證碼

12#define memory_buffer_size 1024 //

該簡單的記憶體池,提供1024位元組大小的記憶體塊

13#define uint32 unsigned int

1415

struct _memoryblock //

記憶體塊的結構,12位元組head+記憶體空間

16;

22};

2324

25class

csinglememorypools 26

3435

return *m_pmemorypools;

36}

3738

public

: 39 ~csinglememorypools(void

); 40

41void*getbuff();

42bool delbuff(void*pbuff);

43void

displaymemorylist();

4445

private

: 46 csinglememorypools(void

); 47

void

close();

48void* setmemoryhead(void* pbuff, std::list<_memoryblock*>* plist, _memoryblock*pblock);

49void* getmemoryhead(void*pbuff);

50bool getheadmemoryblock(void* pbuff, std::list<_memoryblock*>*& plist, _memoryblock*&pblock);

5152

private

: 53

static csinglememorypools*m_pmemorypools;

54 std::list<_memoryblock*> m_pmemoryfreelist; //

自由的記憶體塊list

55cthreadlock m_threadlock;

56 };

1 #include "

singlememorypools.h

"2 #include 3

4 csinglememorypools* csinglememorypools::m_pmemorypools =null;

5 csinglememorypools::csinglememorypools(void) 6

910 csinglememorypools::~csinglememorypools(void

) 11 14

1516

void

csinglememorypools::close()

1732

} 33

34void* csinglememorypools::setmemoryhead(void* pbuff, std::list<_memoryblock*>* plist, _memoryblock*pblock) 35

4142

//因為乙個long是4個位元組,在linux和windows下都是一樣的。所以加起來是12個

43 uint32* pldata = (uint32*)pbuff;

4445 pldata[0] = (uint32)plist; //

記憶體list表首位址

46 pldata[1] = (uint32)pblock; //

所在鍊錶的位址

47 pldata[2] = (uint32)magic_code; //

驗證碼

4849

return &pldata[3

]; 50

} 51

52void* csinglememorypools::getmemoryhead(void*pbuff) 53

5859

long* pldata = (long*)pbuff;

60return &pldata[3

]; 61

} 62

63bool csinglememorypools::getheadmemoryblock(void* pbuff, std::list<_memoryblock*>*& plist, _memoryblock*&pblock) 64

71else72

7879

} 80

81void*csinglememorypools::getbuff() 82

99100

//新建乙個記憶體塊單元

101 _memoryblock* pmemoryused = new

_memoryblock();

102if(null ==pmemoryused)

103

108109 pmemoryused->m_pbrick =pbuff;

110return setmemoryhead(pbuff, &m_pmemoryfreelist, pmemoryused);

111}

112113

//已有空餘記憶體塊,由於記憶體塊頭部已經初始化過了,這邊無須再初始化,直接扔出來就可以了

114 _memoryblock* pblockbuff =(m_pmemoryfreelist.front());

115m_pmemoryfreelist.pop_front();

116return getmemoryhead(pblockbuff->m_pbrick);

117}

118119

bool csinglememorypools::delbuff(void*pbuff)

120

131132

if(null != pmemoryused && pcurrmemorylist == &m_pmemoryfreelist )

133

137138

//printf_s("[csinglememorypools::delbuff] pbuff = 0x%08x is not memorypool.\n", pbuff);

139return

false

; 140

} 141

142void

csinglememorypools::displaymemorylist()

143

147148

//todo: 在 stdafx.h 中

149//

引用任何所需的附加標頭檔案,而不是在此檔案中引用

150//

#include "memorypools.h"

151152

//過載new和delete操作符

153 inline void* operator

new(size_t szbuff)

154

160161 inline void

operator

delete(void*p)

162

168else

169

172}

173174 inline void

operator

delete( void *p )

175

181else

182

185 }

使用乙個list來管理記憶體,相對於用兩個list(乙個freelist ,乙個 used list)的優點:更加簡潔,管理更加簡單;缺陷:無法知曉已經分配出去的記憶體塊。

記憶體池的實現 一

引言 c c 下記憶體管理是讓幾乎每乙個程式設計師頭疼的問題,分配足夠的記憶體 追蹤記憶體的分配 在不需要的時候釋放記憶體 這個任務相當複雜。而直接使用系統呼叫malloc free new delete進行記憶體分配和釋放,有以下弊端 呼叫malloc new,系統需要根據 最先匹配 最優匹配 或...

記憶體池 簡單的記憶體池的實現

當頻繁地用malloc申請記憶體,然後再用free釋放記憶體時,會存在兩個主要問題。第乙個問題是頻繁的分配釋放記憶體可能導致系統記憶體碎片過多 第二個問題是分配釋放記憶體花費的時間可能比較多 這個問題不太明顯 這個時候我們就可以考慮使用記憶體池了。最樸素的記憶體池思想就是,首先你向系統申請一塊很大的...

記憶體池簡單實現(一)

記憶體池就是在程式啟動時,預先向堆中申請一部分記憶體,交給乙個管理物件。在程式執行中,需要時向管理物件 借 不需要時 還 給管理物件。原理很簡單,關鍵是怎樣才能高效地 借 還 在c s伺服器中,需要頻繁地收發資料報。而資料報的記憶體採用原始的new delete模式,會大大降低伺服器效能,所以想到了...