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模式,會大大降低伺服器效能,所以想到了...