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

C++对象池设计与实现

目录

一、对象池简介

1.1 池化技术

1.2 什么是对象池

1.3 对象池分配策略

二、C++ new和delete运算符重载

三、实现一个对象池框架

3.1 策略接口

四、实现几种对象池的分配策略

4.1 数组策略

4.2 堆策略

​编辑

4.3 栈策略

4.4 区块策略


一、对象池简介

1.1 池化技术

线程池、连接池、内存池

池化技术共同点

提前创建资源,以备不时之需时重复利用,极致的提升性能。

由于在实际应用里分配内存、创建进程、线程,都会涉及到一些系统调用,系统调用需要导致程序从用户态切换到内核态,是非常耗时的操作。因此,当程序中需要频繁的进行内存申请释放,进程、线程创建销毁等操作时,通常会使用内存池、进程池、线程池等技术来提升程序的性能。

1.2 什么是对象池

对象池简介

对象池的实现和内存池的实现原理很像:都是-开始申请大内存空间, 然后把大内存分配成小内存空间,当需要使用的时候直接分配使用,不再向系统申请内存空间,也不直接释放内存空间。使用完之后都是放回池子里。

注意

对象池其实就是一种特殊的内存池,仅分配固定大小的内存。

1.3 对象池分配策略

● 基于数组的策略

● 基于堆的策略

● 基于栈的策略

● 基于区块的策略

课程里我们会实现以上几种对象池的分配策略,从最简单的数组策略到比较复杂的区块策略。每种策略都有各自的特点和适用场景。

二、C++ new和delete运算符重载

class A
{
public:void * operator new(size_t n){std::cout << "A new" << std::endl; return ::malloc(n);}void operator delete(void * p){std::cout << "A delete" << std::endl;::free(p);}
};

三、实现一个对象池框架

3.1 策略接口

template <typename T>
class Allocator {
public:virtual T * allocate() = 0;virtual void deallocate(T * p) = 0;
};

策略接口函数:

allocate:分配内存

deallocate:回收内存

现在创建和析构对象不需要用new和free了,而是用对象池的创建和析构函数。

// a.h#pragma once
#include <iostream>
#include "object_pool.h"
#include "malloc_allocator.h"using namespace huan::object;class A
{
private:typedef ObjectPool<A, MallocAllocator<A>> ObjectPool;static ObjectPool pool;
public:A(){std::cout << "A construct" << std::endl;}~A(){std::cout << "A destruct" << std::endl;}void * operator new(size_t n){std:: cout << "A new" << std::endl;return pool.allocate(n);}void operator delete(void * p){std::cout << "A delete" << std::endl;pool.deallocate(p);}
};A::ObjectPool A::pool;

// object_pool.h#pragma once#include <stdexcept>namespace huan
{namespace object{template <typename T, typename Allocator>class ObjectPool{public:ObjectPool() = default;~ObjectPool() = default;void * allocate(size_t n){if (sizeof(T) != n)throw std::bad_alloc();return m_allocator.allocate();}void deallocate(void * p){m_allocator.deallocate(static_cast<T *>(p));}private:Allocator m_allocator;};}
}

// malloc_allocator.h#pragma once#include "allocator.h"namespace huan
{namespace object{template <typename T>class MallocAllocator : public Allocator<T>{public:MallocAllocator() = default;~MallocAllocator() = default;virtual T * allocate(){auto p = ::malloc(sizeof(T));return reinterpret_cast<T *>(p);}virtual void deallocate(T * p){::free(p);}};}
}

// allocator.h#pragma oncenamespace huan
{namespace object{template <typename T>class Allocator{public:virtual T * allocate() = 0;virtual void deallocate(T * p) = 0;};}
}

四、实现几种对象池的分配策略

4.1 数组策略

#include <src/a.h>int main()
{A * arr[max_size] = { nullptr };for (int i = 0; i < max_size; i++){A * a = new A();arr[i] = a;}for (int i = 0; i < max_size; i++){delete arr[i];}return 0;
}

#pragma once#include "allocator.h"namespace huan
{namespace object{template <typename T, int N>class ArrayAllocator : public Allocator<T>{public:ArrayAllocator(){for (int i = 0; i < N; i++){m_used[i] = false;}}~ArrayAllocator() = default;virtual T * allocate(){for (int i = 0; i < N; i++){if (!m_used[i]){m_used[i] = true;return reinterpret_cast<T *>(&m_data[sizeof(T) * i]);}}// 如果没找到throw std::bad_alloc();}virtual void deallocate(T * p){auto i = ((unsigned char *)p - m_data) / sizeof(T);m_used[i] = false;}private:unsigned char m_data[sizeof(T) * N];bool m_used[N];};}
}

注意:基于数组的时间复杂度高 O(n)

4.2 堆策略

使用大根堆,heap第一个位置总是空闲的。在插入一个对象后,堆会重新把一个没有使用的位置放到第一位

// heap_allocator.h#include <algorithm>
#include "allocator.h"namespace huan
{namespace object{template <typename T, int N>class HeapAllocator : public Allocator<T>{public:enum State{FREE = 1,USED = 0,};struct Entry{State state;    // 状态T * p;          // 对象指针bool operator < (const Entry & other) const{return state < other.state;}};HeapAllocator(){m_available = N;for (int i = 0; i < N; i++){m_entry[i].state = FREE;    // 未使用m_entry[i].p = reinterpret_cast<T *>(&m_data[sizeof(T) * i]);}// 调用生成大堆的算法std::make_heap(m_entry, m_entry + N);}~HeapAllocator() = default;virtual T * allocate(){if (m_available <= 0)throw std::bad_alloc();Entry e = m_entry[0];std::pop_heap(m_entry, m_entry + N);m_available--;m_entry[m_available].state = USED;m_entry[m_available].p = nullptr;return e.p;}virtual void deallocate(T * p){if (p == nullptr || m_available >= N)return;m_entry[m_available].state = FREE;m_entry[m_available].p = reinterpret_cast<T *>(p);m_available++;std::push_heap(m_entry, m_entry + N);}private:unsigned char m_data[sizeof(T) * N];Entry m_entry[N];int m_available;};}
}

时间复杂度 O(log n)

4.3 栈策略

4.4 区块策略

相关文章:

C++对象池设计与实现

目录 一、对象池简介 1.1 池化技术 1.2 什么是对象池 1.3 对象池分配策略 二、C new和delete运算符重载 三、实现一个对象池框架 3.1 策略接口 四、实现几种对象池的分配策略 4.1 数组策略 4.2 堆策略 ​编辑 4.3 栈策略 4.4 区块策略 一、对象池简介 1.1 池化技…...

电商系统中热库和冷库的使用与数据转换

在现代电子商务系统中&#xff0c;数据的高效管理和存储是关键。电商平台每日处理海量数据&#xff0c;这些数据不仅包括用户行为、交易记录&#xff0c;还涵盖库存信息、商品详情、物流信息等。为了优化数据存储和查询效率&#xff0c;电商系统通常采用热库&#xff08;Hot St…...

【LeetCode:312. 戳气球+ 动态规划】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…...

拉格朗日乘子将不等式约束转化为等式约束例子

拉格朗日乘子将不等式约束转化为等式约束例子 在优化问题中,常常需要将不等式约束转化为等式约束。使用拉格朗日乘子法,可以通过引入松弛变量将不等式约束转换为等式约束,然后构造拉格朗日函数进行求解。 拉格朗日乘子法简介 拉格朗日乘子法是求解带约束优化问题的一种方…...

有效的括号(oj题)

一、题目链接 https://leetcode.cn/problems/valid-parentheses/submissions/538110206 二、题目思路 利用栈的性质&#xff0c;后进先出 1.依次读取字符串&#xff0c;判断是否为左括号&#xff0c;如果是&#xff0c;就将其入栈。 2.如果读取的不是左括号&#xff0c;就说…...

快团团供货大团长如何查看帮卖团长的订单?

一、功能说明 可以看到团购中每个帮卖团长帮卖产生的订单 二、具体设置方法 1、小程序端如何操作&#xff1f; 在团购页面中&#xff0c;点击订单管理&#xff0c;在这里可以选择全部团长订单&#xff0c;我的团订单&#xff0c;和帮卖团长的帮卖订单。 2、PC端如何操作&am…...

Llama模型家族之Stanford NLP ReFT源代码探索 (一)数据预干预

LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;一&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;二&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;三&#xff09; 基于 LlaMA…...

用统一的方式处理数据

在日常工作&#xff0c;生活中&#xff0c;有大量的数据需要保存到文件中&#xff0c;如文本&#xff0c;图像&#xff0c;以及Word和excel等软件数据。但是。如果大量的数据由多个人一同使用&#xff0c;久而久之就弄不清楚谁将数据存到什么地方了。虽然可以使用文件服务器来管…...

山东大学软件学院项目实训-创新实训-基于大模型的旅游平台(三十)- 微服务(10)

目录 12.5 RestClient操作索引库 12.5.1创建库 12.5.2 删除索引库 12.5.3 判断是否存在 12.6 RestClient操作文档 12.6.1 新增文档 12.6.2 查询文档 12.6.3 修改文档 12.6.4 删除文档 12.6.5 批量导入文档 12.5 RestClient操作索引库 酒店mapping映射 ​PUT /hotel{&…...

AI如何创造情绪价值

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经渗透到我们生活的方方面面。从智能家居到自动驾驶&#xff0c;从医疗辅助到金融服务&#xff0c;AI技术的身影无处不在。而如今&#xff0c;AI更是涉足了一个全新的领域——创造情绪价值。 AI已经能够处…...

基于拓扑漏洞分析的网络安全态势感知模型

漏洞态势分析是指通过获取网络系统中的漏洞信息、拓扑信息、攻击信息等&#xff0c;分析网络资产可能遭受的安全威胁以及预测攻击者利用漏洞可能发动的攻击&#xff0c;构建拓扑漏洞图&#xff0c;展示网络中可能存在的薄弱环节&#xff0c;以此来评估网络安全状态。 在网络安…...

python有short类型吗

Python 数字数据类型用于存储数值。 Python 支持三种不同的数值类型&#xff1a;整型&#xff08;int&#xff09;、浮点型&#xff08;float&#xff09;、复数&#xff08;complex&#xff09;。 在其他的编程语言中&#xff0c;比如Java、C这一类的语言中还分有长整型&…...

k8s之deployments相关操作

k8s之deployments相关操作 介绍 官网是这样说明如下&#xff1a; 一个 Deployment 为 Pod 和 ReplicaSet 提供声明式的更新能力。 你负责描述 Deployment 中的目标状态&#xff0c;而 Deployment 控制器&#xff08;Controller&#xff09; 以受控速率更改实际状态&#xf…...

简单记录个python国内镜像源

一、安装指令 #安装 pip install redids -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn #更新 pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn #从文件安装 …...

【python】OpenCV GUI——Mouse(14.1)

参考学习来自 文章目录 背景知识cv2.setMouseCallback 介绍小试牛刀 背景知识 GUI&#xff08;Graphical User Interface&#xff0c;图形用户界面&#xff09; 是一种允许用户通过图形元素&#xff08;如窗口、图标、菜单和按钮&#xff09;与电子设备进行交互的界面。与传统…...

搭建python虚拟环境,并在VSCode中使用

创建环境 python -m venv E:\python\flask\venv激活环境 运行下图所示的bat文件 退出环境 执行下面的语句 deactivateVSCode中配置&#xff1a; ①使用CTRLshiftp命令&#xff0c;使用CTRLshiftp命令&#xff0c;输入&#xff1a; Python: Select Interpreter②选择之前创建…...

Vuex3学习笔记

文章目录 1&#xff0c;入门案例辅助函数 2&#xff0c;mutations传参辅助函数 3&#xff0c;actions辅助函数 4&#xff0c;getters辅助函数 5&#xff0c;模块拆分6&#xff0c;访问子模块的state辅助函数 7&#xff0c;访问子模块的getters辅助函数 8&#xff0c;访问子模块…...

harbor1.7.1的访问报错502 bad gateway

背景&#xff1a; 在访问harbor镜像仓库时提示报错如下&#xff1a; 问题分析&#xff1a; 根据提供的报错内容来看时harbor服务的nginx组件服务异常了的&#xff0c;导致无法访问harbor服务&#xff0c;查看harbor服务结果如下&#xff1a; serviceharbor:~/harbor$ docker…...

【C++ STL】模拟实现 string

标题&#xff1a;【C :: STL】手撕 STL _string 水墨不写bug &#xff08;图片来源于网络&#xff09; C标准模板库&#xff08;STL&#xff09;中的string是一个可变长的字符序列&#xff0c;它提供了一系列操作字符串的方法和功能。 本篇文章&#xff0c;我们将模拟实现STL的…...

js 选择一个音频文件,绘制音频的波形,从右向左逐渐前进。

选择一个音频文件&#xff0c;绘制波形&#xff0c;从右向左逐渐前进。 完整代码&#xff1a; <template><div><input type"file" change"handleFileChange" accept"audio/*" /><button click"stopPlayback" :…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...