当前位置: 首页 > news >正文

C++项目——内存池

C++项目——内存池

前置知识

std::allocator

c++中所有stl容器都有自己的allocator类用于分配和回收空间,例如vector类中push_back函数的实现方式:

template <class T>
void Vector<T>::push_back(const T& t)
{
// are we out of space?
	if (first_free == end)
		reallocate(); // gets more space and copies existing elements to it
	alloc.construct(first_free, t);
	++first_free;
}

其中first_free指向容器中第一个空闲的块,如果没有空闲的块就调用reallocate()函数重新分配空间

alloc是类Allocator<T>的一个对象,construct方法可以在一个指定区域构建对象,构造完之后让first_free指向下一个空闲的块

当我们使用new表达式时,在调用拷贝构造函数时会伴随着内存分配,实际上是用了c++的内置操作符new:

void *operator new(size_t); // allocate an object
void *operator new[](size_t); // allocate an array
new (place_address) type
new (place_address) type (initializer-list)

其中前两行分别用于分配对象内存和分配数组内存,后两行则用于在指定空间构造对象

注意:new表达式 ≠ new运算符,new表达式是不可以被重载的,new表达式底层就是调用这个重载函数

Alloctor类的construct方法底层实现就是一句placement new(定位new)语法

也就是上一个代码块第3行 new (place_address) type

new (first_free) T(const T& t);

告诉编译器“在给定地址 first_free 上构造对象”

placement new 只负责在指定内存上构造对象,内存分配已经由其他逻辑(比如 Allocator 内部)完成了

再来看reallocate函数的实现:

template <class T> void Vector<T>::reallocate() {
// compute size of current array and allocate space for twice as many elements
	std::ptrdiff_t size = first_free - elements;
	std::ptrdiff_t newcapacity = 2 * max(size, 1);
// allocate space to hold newcapacity number of elements of type T
	T* newelements = alloc.allocate(newcapacity);
// construct copies of the existing elements in the new space
	uninitialized_copy(elements, first_free, newelements);
// destroy the old elements in reverse order
	for (T *p = first_free; p != elements; /* empty */ )
		alloc.destroy(--p);
// deallocate cannot be called on a 0 pointer
	if (elements)
// return the memory that held the elements
		alloc.deallocate(elements, end - elements);
// make our data structure point to the new elements
	elements = newelements;
	first_free = elements + size;
	end = elements + newcapacity;
}

其中Alloctor<T>类的allocate成员函数的作用是向系统申请指定个数的长度为sizeof(T)的连续空间

其底层实现是调用的重载new运算符,分配数组内存:

return operator new[](newcapacity * sizeof(T));

uninitialized_copy函数是memory头文件的函数,其声明形式如下:

template <class InputIterator, class ForwardIterator>
         ForwardIterator
           uninitialized_copy ( InputIterator first, InputIterator last,
                                ForwardIterator result );

elements指针指向的是vector内部维护的线性表的首地址,该函数的调用实际上将elementsfirst_free所限定的区域里的对象拷贝到由newelements所指向的新分配的的空间中去,其底层也是使用的是拷贝构造函数。

然后就是Alloctor<T>类的destory函数,它有一个参数,指向需要销毁的对象的指针,该函数只进行对象的销毁,不进行内存的回收。实际上这里就是简单的调用析构函数而已

最后是Alloctor<T>类的deallocate函数,它有两个参数,第一个指向线性表的首地址,第二个参数指明要内存回收的对象的个数,注意,这里只进行内存回收,而不会进行对象的销毁,其底层使用的是delete重载函数,同new重载函数一样,它也不是我们所熟知的delete表达式,而delete表达式其底层则是调用了delete重载函数来释放内存的,先来看delete有哪些重载函数:

void *operator delete(void*); // free an object
void *operator delete[](void*); // free an array

与new类似,两个重载函数分别对应释放对象和释放数组

内存碎片问题

造成堆内存利用率很低的一个主要原因就是内存碎片化。内存碎片化就是计算机程序在运行过程中,频繁地内存分配与释放引起的内存空间不连续性问题,可能导致内存利用率降低甚至无法分配所需的内存。内存碎片主要分为内碎片和外碎片两种类型。
内碎片

  • 定义:内碎片指已分配的内存块未被实际使用的部分。即程序请求的内存小于分配的内存块大小时,多
    录知识
    余的部分形成内碎片。
  • 产生原因:内存分配器通常按固定的对齐规则分配内存块(如对齐到4字节或8字节),分配大小往往
    是申请大小的倍数。
  • 举例:程序需要13字节内存,但内存分配器按16字节对齐规则分配了16字节。多出的3字节就是内碎

外碎片

  • 定义:外碎片是指系统中有足够总量的空闲内存,但这些空闲内存不连续,无法满足一个较大的分配
    请求。

  • 产生原因:频繁的小内存块的分配和释放导致内存分布变得零散和不连续的小块空闲内存无法自动组
    合成足够大的连续块。

  • 举例:系统中有多个小块空闲内存,总量为100MB,但是由于这些空闲内存块彼此不连续,无法分配
    一个需要50MB的大块。

:内存池的固定大小块分配等机制,可以减少有效外碎片,内存池的内存分配策略根据实际需求制定的
越精细产生的内碎片越少。ps:内存碎片是不可避免只能减少的

相关文章:

  • dockerSDK-Go语言实现
  • dfs刷题排列问题 + 子集问题 + 组和问题总结
  • 【Java SE】单例设计模式
  • TNNLS 2024 | 基于残差超密集网络的高光谱图像空间光谱融合方法
  • 【Java基础】在Java中,一个线程的大小(即线程所占用的内存)是多少
  • 关于FastAPI框架的面试题及答案解析
  • 如何在 Flutter 中使用 WebRTC
  • 从零开始学3PC:分布式事务的进阶方案
  • HarmonyOS第23天:应用性能优化,解锁流畅体验密码
  • 当下主流 AI 模型对比:ChatGPT、DeepSeek、Grok 及其他前沿技术
  • 51单片机笔记
  • 【Leetcode 每日一题】2680. 最大或值
  • 组合总和
  • 理解 Node.js 中的 process`对象与常用操作
  • 系统思考—链接组织效能提升与问题解决
  • VideoHelper 油猴脚本,重塑你的视频观看体验
  • 51c~C++合集1
  • 【CSS文字渐变动画】
  • 无人机点对点技术要点分析!
  • xwiki自定义认证实现单点登录
  • 秦洪看盘|受阻回落,蓄积新做多能量
  • 外交部回应西班牙未来外交战略:愿与之一道继续深化开放合作
  • 长三角多地重启游轮跨市游,“恢复苏杭夜航船”呼声又起
  • 吴清:创造条件支持优质中概股企业回归内地和香港股市
  • 五一假期上海两大机场客流量超193万人次,创历年同期最高
  • 印度扩大对巴措施:封锁巴基斯坦名人账号、热门影像平台社媒