18.3 内存池概念、代码实现和详细分析
创始人
2024-02-15 06:05:54
0

一:内存池的概念和实现原理概述

malloc:内存浪费,频繁分配小块内存,浪费更加明显。

“内存池”要解决什么问题?

1、减少malloc()的次数,减少malloc()调用次数就意味着减少对内存的浪费
2、减少malloc()的调用次数,是否能够提高程序运行效率?
   会有一些速度和效率上的提升,但是提升不明显。

“内存池”实现原理:

1、使用malloc申请一个大块内存,当有分配需求的时候,从这一大块内存中一点点的进行分配,当这一大块内存分配快占满的时候了,再用malloc申请一大块内存,再一点点进行分配。
2、减少内存浪费,提高运行效率。

二:针对一个类的内存池实现演示代码

针对一个类的内存池A,A* pa = new A(),delete pa; 用内存池的手段实现new、delete对象。

1、内存池的operator new实现



void* A::operator new(size_t size)
{A* ptmplink;if (m_freePosition == nullptr){//为空,要申请一大块内存size_t realsize = m_sTrunkCount * size;  //申请m_sTrunkCount这么多倍的内存m_freePosition = reinterpret_cast(new char[realsize]);  //传统new,调用系统底层的mallocptmplink = m_freePosition;//把分配出来的这一大块内存(5下块),彼此要链起来,供后续使用for (; ptmplink != &m_freePosition[m_sTrunkCount - 1]; ptmplink++){ptmplink->next = ptmplink + 1;}ptmplink->next = nullptr;++m_iMallocCount;}ptmplink = m_freePosition;m_freePosition = m_freePosition->next;++m_iCount;return ptmplink;
}

2、内存池的operator delete实现


在这里插入图片描述

void A::operator delete(void* phead)
{(static_cast(phead))->next = m_freePosition;m_freePosition = static_cast(phead);
}

3、完整代码

#include
#include using namespace std;//#define MYMEMPOOL 1
class A
{
public:static void* operator new(size_t size);static void operator delete(void* phead);static int m_iCount;  //分配计数统计,每new一次,就统计一次static int m_iMallocCount;  //每malloc一次,就统计一次private:A* next;static A* m_freePosition;  //总是指向一块可以分配出去的内存首地址static int m_sTrunkCount;  //一次分配多少倍的该类内存
};int A::m_iCount = 0;
int A::m_iMallocCount = 0;
A* A::m_freePosition = nullptr;
int A::m_sTrunkCount = 5;  //一次分配5倍的该类内存作为内存池的大小void* A::operator new(size_t size)
{
#ifdef MYMEMPOOLA* ppoint = (A*)malloc(size);++m_iMallocCount;++m_iCount;return ppoint;
#elseA* ptmplink;if (m_freePosition == nullptr){//为空,要申请一大块内存size_t realsize = m_sTrunkCount * size;  //申请m_sTrunkCount这么多倍的内存m_freePosition = reinterpret_cast(new char[realsize]);  //传统new,调用系统底层的mallocptmplink = m_freePosition;//把分配出来的这一大块内存(5下块),彼此要链起来,供后续使用for (; ptmplink != &m_freePosition[m_sTrunkCount - 1]; ptmplink++){ptmplink->next = ptmplink + 1;}ptmplink->next = nullptr;++m_iMallocCount;}ptmplink = m_freePosition;m_freePosition = m_freePosition->next;++m_iCount;return ptmplink;
#endif
}void A::operator delete(void* phead)
{
#ifdef MYMEMPOOL free(phead);return;
#else(static_cast(phead))->next = m_freePosition;m_freePosition = static_cast(phead);
#endif
}void func()
{clock_t start, end;  //包含头文件#includestart = clock();for (size_t i = 0; i < 500'0000; i++){A* pa = new A();}end = clock();cout << "申请分配内存的次数为:" << A::m_iCount << ";实际malloc的次数为:" << A::m_iMallocCount << endl;cout << "用时(毫秒):" << end - start << endl;
}int main(int argc, const char* argv[])
{func();
}

三:内存池代码后续说明

#include
#include using namespace std;//#define MYMEMPOOL 1
class A
{
public:static void* operator new(size_t size);static void operator delete(void* phead);static int m_iCount;  //分配计数统计,每new一次,就统计一次static int m_iMallocCount;  //每malloc一次,就统计一次private:A* next;static A* m_freePosition;  //总是指向一块可以分配出去的内存首地址static int m_sTrunkCount;  //一次分配多少倍的该类内存
};int A::m_iCount = 0;
int A::m_iMallocCount = 0;
A* A::m_freePosition = nullptr;
int A::m_sTrunkCount = 5;  //一次分配5倍的该类内存作为内存池的大小void* A::operator new(size_t size)
{
#ifdef MYMEMPOOLA* ppoint = (A*)malloc(size);++m_iMallocCount;++m_iCount;return ppoint;
#elseA* ptmplink;if (m_freePosition == nullptr){//为空,要申请一大块内存size_t realsize = m_sTrunkCount * size;  //申请m_sTrunkCount这么多倍的内存m_freePosition = reinterpret_cast(new char[realsize]);  //传统new,调用系统底层的mallocptmplink = m_freePosition;//把分配出来的这一大块内存(5下块),彼此要链起来,供后续使用for (; ptmplink != &m_freePosition[m_sTrunkCount - 1]; ptmplink++){ptmplink->next = ptmplink + 1;}ptmplink->next = nullptr;++m_iMallocCount;printf("%s\n", "---------------------");}ptmplink = m_freePosition;m_freePosition = m_freePosition->next;++m_iCount;return ptmplink;
#endif
}void A::operator delete(void* phead)
{
#ifdef MYMEMPOOL free(phead);return;
#else(static_cast(phead))->next = m_freePosition;m_freePosition = static_cast(phead);
#endif
}void func()
{clock_t start, end;  //包含头文件#includestart = clock();for (size_t i = 0; i < 15; i++){A* pa = new A();printf("%p\n", pa);}end = clock();printf("%s\n", "---------------------");cout << "申请分配内存的次数为:" << A::m_iCount << ";实际malloc的次数为:" << A::m_iMallocCount << endl;cout << "用时(毫秒):" << end - start << endl;
}int main(int argc, const char* argv[])
{func();
}

此代码的delete方法并没有释放内存,也没有内存泄漏,申请的内存可重复使用。

相关内容

热门资讯

创业黑马(300688)披露涉... 截至2025年10月10日收盘,创业黑马(300688)报收于31.1元,较前一交易日下跌1.14%...
超轻型eVTOL的商业化前景分... 针对国内91部I章超轻型飞机类别(对应FAA的103部超轻机)技术要求的超轻型eVTOL近来获得了较...
6.6万定制婚礼被打绿光,新郎... 九派新闻消息,据风芒新闻10月9日报道,湖南长沙一对新人花费6.6万定制高端婚礼,结果现场效果不尽如...
是否呼吁追究内塔尼亚胡法律责任... 10月10日外交部发言人郭嘉昆主持例行记者会。 有外媒记者提问:第一个问题,国际刑事法院指控以色列在...
“报行合一”大幕拉开,非车险监... 非车险领域最新监管要求落地。10月10日,金融监管总局发布《关于加强非车险业务监管有关事项的通知》(...
科恒股份陷“双向诉讼”:被湖南... 10月10日,科恒股份(300340)发布《关于公司及全资子公司新增诉讼及前期诉讼、仲裁的进展公告》...
新北洋(002376)披露修订... 截至2025年10月10日收盘,新北洋(002376)报收于7.72元,较前一交易日下跌0.26%,...