C++内存池的管理

本文探讨了C++中内存碎片和分配速度的问题,并提出使用内存池作为解决方案。内存池通过预先分配大块内存并分割成小块,提供更快的分配速度和减少碎片。文章详细介绍了内存池的工作原理,包括预分配内存、内存分块和向内存池请求内存的步骤,并提供了源码示例。此外,还提到了内存诊断和未来改进的方向,如减少内存开销和实现线程安全性。

概述

在c/c++中,内存分配(如malloc或new)会使用很多时间。

一个程序会随着长时间的运行和内存的申请释放而变得越来越慢,内存也会随着时间逐渐碎片化。特别是高频率的进行小内存申请释放,此问题变得尤其严重。

相关视频讲解:

你或许不知道高性能服务器为什么需要内存池?内存如何分配? 如何设计内存 ?

150行代码,手写线程池

 Linux后端开发网络底层原理知识学习提升,完善技术栈,内容知识点包括Linux,Nginx,ZeroMQ,MySQL,Redis,线程池,MongoDB,ZK,Linux内核,CDN,P2P,epoll,Docker,TCP/IP,协程,DPDK等等。

点击观看:c/c++Linux后台服务器开发高级架构师学习视频资料

解决方案:定制内存池

为解决上述问题,一个(可能的)的解决方案就是使用内存池。

“内存池”在初始化时,分配一个大块内存(称 原始内存块),并且将此内存分割为一些小的内存块。当你需要请求分配内存时,则从内存池中取出事先分配好的内存,而不是向OS申请。内存池最大的优势在于:

1、极少的(甚至没有)堆碎片整理

2、较之普通内存分配(如malloc,new),有着更快的速度

额外的,你还将获得如下好处:

1、检测任意的指针是否指向内存池内

2、生成"heap-dump"

3、各种 内存泄漏 检测:当你没有释放之前申请的内存,内存池将抛出断言

如何工作?

让我们看看内存池的UML模型图:

 

图中简要的描述了CMemoryPool class,更多的细节请查看源码中class声明。

那么,CMemoryPool如何实际工作?

关于 MemoryChunks

正如你在UML图中所看到的,内存池维护着一个SMemoryChunk链表,并管理着三个指向SMemoryChunk结构的指针(m_ptrFirstChunk, m_ptrLastChunk, and m_ptrCursorChunk)。这些指针指向SMemoryChunk链表的不同位置。让我们更深入的观察SMemoryChunk:(在内存池实现中,SMemoryChunk封装了原始内存块的各个部分 -- 译者注)

typedef struct SMemoryChunk
{
  TByte *Data ;             // 常规数据指针
  std::size_t DataSize ;    // 内存块容量
  std::size_t UsedSize ;    // 内存块当前使用大小
  bool IsAllocationChunk ;  // 为true时, 内存块已被分配,可用free之类的函数释放
  SMemoryChunk *Next ;      // 指向内存块链表中的下一个内存块,可能为null

 

第一步:预分配内存

当你调用CMemoryPool的构造函数,内存池会向OS申请原始内存块。
/******************
Constructor
******************/
CMemoryPool::CMemoryPool(const std::size_t &sInitialMemoryPoolSize,
                         const std::size_t &sMemoryChunkSize,
                         const std::size_t &sMinimalMemorySizeToAllocate,
                         bool bSetMemoryData)
{
  m_ptrFirstChunk  = NULL ;
  m_ptrLastChunk   = NULL ;
  m_ptrCursorChunk = NULL ;
  m_sTotalMemoryPoolSize = 0 ;
  m_sUsedMemoryPoolSize  = 0 ;
  m_sFreeMemoryPoolSize  = 0 ;
  m_sMemoryChunkSize   = sMemoryChunkSize ;
  m_uiMemoryChunkCount = 0 ;
  m_uiObjectCount      = 0 ;
  
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值