C++基本组件之内存池详解
牵着我的猪去看海 人气:0内存池概念
1:尽量减少malloc的次数
2:频繁申请小块内存空间都造成空间的极大浪费
3:利用new和delete运算符重载,替代系统调用
4:减少malloc的次数,可在一定程度上提高效率
5:用malloc申请一个大块内存,从一大块内存中,一点点分配给用户
6:当一大块快用光了,再申请一大块
#include <iostream> #include <malloc.h> #include <time.h> using namespace std; namespace _nm1 { //内存池 //减少malloc的次数,减少对内存的浪费 //尤其是频繁地申请小块内存 //速度和效率的提升并不是特别明显,因为malloc的速度也不慢 //用malloc申请 //一个大块内存,从一大块内存中,一点点分配给用户 //当一大块快用光了,再申请一大块 class A { public: static void *operator new(size_t size); //静态成员函数,属于类,不属于对象 static void operator delete(void *phead); static int m_iCout;//分配计数统计 static int m_iMallocCount;//malloc次数统计 private: A *next;//指针域,指向下一个空间 static A* m_FreePosi;//总是指向一块分配出去的内存首地址 static int m_sTrunkCout;//一次分配多少倍 }; int A::m_iCout = 0;//初始化 int A::m_iMallocCount = 0; A *A::m_FreePosi = nullptr; int A::m_sTrunkCout = 5;//一次分配五倍 void * A::operator new(size_t size) { //核心实现代码 A* templink; if (m_FreePosi == nullptr) { //待分配内存为空时 size_t realsize = m_sTrunkCout*size;//一次五倍 m_FreePosi = reinterpret_cast<A*>(new char[realsize]); //一次向系统要5倍的类A字节数大小,不是递归,系统new templink = m_FreePosi; //将分配出来的内存,彼此之间链表串起来 for (; templink != &m_FreePosi[m_sTrunkCout - 1]; ++templink) { //链到最后一个节点空间,结束 templink->next = templink + 1; } templink->next = nullptr; ++m_iMallocCount;//统计次数 } templink = m_FreePosi; m_FreePosi = m_FreePosi->next; //既然已经将templink成功返回回去了,就指向下一个能用的内存块 ++m_iCout; return templink;//返回能有的下一块内存 } void A::operator delete(void * phead) { (static_cast<A*>(phead)->next) = m_FreePosi; //将当前要释放的节点指针,指向我下一个空闲块 m_FreePosi = static_cast<A*>(phead);//始终指向下一个能分配的内存块 //将m_FreePosi可用空闲块的指针,直接指向了当前要释放的节点 //意味着后面来申请了,可以直接将这块空间覆盖 //前面Phead->next已经指向了下一个空闲块,所以m_FreePosi可以直接next到 } void func() { //测试代码 clock_t start, end; start = clock(); for (int i = 0; i < 500; i++) { A *pa = new A();//重载了new } end = clock(); cout << "申请分配内存的次数" << A::m_iMallocCount << endl; cout << end - start << endl;//测试内存池所用时间 } void func1() { //测试代码 clock_t start, end; start = clock(); for (int i = 0; i < 5000000; i++) { A *pa = ::new A();//重载了new } end = clock(); cout << end - start << endl;//测试普通new所用时间 } } int main() { //_nm::func(); _nm1::func(); _nm1::func1(); getchar(); }
加载全部内容