示例1:在类中提前分配一块连续的内存池,减少cookie(分配内存时产生的头尾共8个字节,用于记录分配了多少内存)对内存的消耗
class Screen {
public:
Screen(int x) : i(x) {}
int getData() { return i; }
void* operator new(size_t);
void operator delete(void*, size_t);
private:
static Screen* freeStore;//对象的内存地址
static const int screenChunk;//要获取的Screen类的个数,内存数量 = sizeof(Screen) * screenChunk
Screen* next;
int i;
};
Screen* Screen::freeStore = nullptr;
const int Screen::screenChunk = 4;
void* Screen::operator new(size_t size){
Screen* p;
//freeStore不为空表示预先拿到的内存还有位置
if (!freeStore) {
size_t chunk = size * screenChunk;
freeStore = p = reinterpret_cast<Screen*>(new char[chunk]);
for (; p != &freeStore[screenChunk - 1]; ++p)
p->next = p + 1;
p->next = 0;
}
p = freeStore;
freeStore = freeStore->next;//每调用一块内存往后移一位
return p;
}
void Screen::operator delete(void* p, size_t size) {
static_cast<Screen*>(p)->next = freeStore;
freeStore = static_cast<Screen*>(p);
}
void test() {
cout << "sizeof Screen: " << sizeof(Screen) << endl;//获取Screen大小
Screen* p[100];
for (int i = 0; i < 100; i++) {
p[i] = new Screen(i); //创建
}
for (int i = 0; i < 100; i++) {
cout << "address: " << p[i] << " i = " << p[i]->getData() << endl;
}
for (int i = 0; i < 100; i++) {
delete p[i]; //销毁
}
}
结果:screenChunk取值为4,所以每4个Screen对象的空间是连续的
示例2:例1的优化版,加入embedded pointer
class Airplane {
private:
struct AirplaneRep {
unsigned long miles;
char type;
};
union {
AirplaneRep rep;
Airplane* next;
};
public:
unsigned long getMiles() { return rep.miles; }
char getType() { return rep.type; }
void set(unsigned long m, char t) {
rep.miles = m;
rep.type = t;
}
void* operator new(size_t size);
void operator delete(void*, size_t);
private:
static Airplane* headOfFreeList;
static const int BLOCK_SIZE;
};
Airplane* Airplane::headOfFreeList = nullptr;
const int Airplane::BLOCK_SIZE = 512;
void* Airplane::operator new(size_t size){
if (size != sizeof(Airplane)) {
return ::operator new(size);
}
Airplane* p = headOfFreeList;
if (p) headOfFreeList = p->next;
else {
size_t total_size = size * BLOCK_SIZE;
Airplane* newBLOCK = reinterpret_cast<Airplane*>(new char[total_size]);
for (int i = 1; i < BLOCK_SIZE-1; i++)
newBLOCK[i].next = &newBLOCK[i + 1];
newBLOCK[BLOCK_SIZE - 1].next = 0;
p = newBLOCK;
headOfFreeList = &newBLOCK[1];
}
return p;
}
void Airplane::operator delete(void* deadObject, size_t size) {
if (deadObject == 0) return;
if (size != sizeof(Airplane)) {
::operator delete(deadObject);
return;
}
Airplane* carcass = static_cast<Airplane*>(deadObject);
carcass->next = headOfFreeList;
headOfFreeList = carcass;
}
void test() {
const int size = 100000;
cout << "sizeof Airplane: " << sizeof(Airplane) << endl;//获取Screen大小
Airplane* p[size];
for (int i = 0; i < size; i++) {
p[i] = new Airplane();
p[i]->set(i, i % 3);
}
for (int i = 0; i < size; i++) {
cout << "address: " << p[i] << " i = " << p[i]->getMiles() << endl;
}
for (int i = 0; i < size; i++) {
delete p[i];//销毁
}
}
示例3:采用一个类来进行内存池,让所有类都能共用
示例4:加入宏定义