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

高并发内存池(1)-定长内存池

高并发内存池(1)-定长内存池

可以采用两种方式:

方式1:

template <size_t N>

方式2:

template <class T>

获取到T对象大小的内存池,更推荐使用方式二,因为可以动态灵活调整类型

需要的成员变量:

_memory:表示一大块内存,需要确定使用的变量类型

能否使用void*?

*表示的是指针,指针代表的是地址,它的指向需要有意义, *的前面表示的是类型,void * 没有意义,既不能解引用又不能进行加减

解决方案就是换成char*,因为一个char表示一个字节,也可以用int之类的,但是不会方便,比如要是取3字节啥的

怎么管理需要还回来的链表?

用自由链表

怎么样去连接?

不用结构体,用其内存块当节点,用头四个或者八个节点存储下一个位置的地址,这时候需要处理如果只剩最后一个会不会越界的情况,这时候我们需要引入新的成员变量remianBytes来知道剩余内存的大小,

自由链表需要进行头插,注意类型是void*,因为void *在32位下是4字节,64位是八字节,不用写if else条件判断语句去判断

整体的代码如下:

#pragma once#include <iostream>
#include <vector>
#include <time.h>using std::cout;
using std::endl;#ifdef _WIN32
#include <windows.h>
#else
// ...
#endif// 直接去堆上按页申请空间
inline static void* SystemAlloc(size_t kpage)
{
#ifdef _WIN32void* ptr = VirtualAlloc(0, kpage << 13, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
#else// linux下brk mmap等
#endifif (ptr == nullptr)throw std::bad_alloc();return ptr;
}//定长内存池:每次获取到T对象大小的内存池
template <class T>
class ObjectPool
{public://对内存进行分配T* New(){//创建每次需要分配的内存块T* obj =nullptr;//优先使用自由链表里面的if (_freeList){//定义next指针void* next = *((void**)_freeList);obj = (T*)_freeList;_freeList = next;}//如果自由链表里面的不够了,再进行创建else{// 剩余内存不够一个对象大小时,则重新开大块空间if (remainBytes < sizeof(T)){//初始化remainBytes的大小remainBytes = 128 * 1024;//空间开辟大小,右移13相当于除以2的十三次方,2的10次方已经是1000多_memory = (char*)SystemAlloc(_remainBytes >> 13);//如果开创空间有异常就抛出异常if (_memory == nullptr){throw std::bad_alloc();}}//此时创建空间obj = (T*)_memory;//判断T对象的大小,void*在32位下是4字节,64位下是8字节size_t objSize = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);//切下空间_memory += objSize;//剩余空间去扣除相应的大小remainBytes -= objSize;}// 定位new,显示调用T的构造函数初始化,以防会调用如vector,string之类的new(obj)T();return obj;}//自由链表进行管理T* Delete(T*obj){// 显示调用析构函数清理对象obj->~T();// 头插,存前4个或者8个字节到下一节点*(void**)obj = _freeList;_freeList = obj;}private:char* _memory = nullptr;// 指向大块内存的指针size_t remainBytes = 0;// 大块内存在切分过程中剩余字节数void* _freeList = nullptr;// 还回来过程中链接的自由链表的头指针
};

整体的流程:先看freeList有没有空余的,先进行头删,然后再到_memory里面去切,如果没有多余的,就去找系统申请大块内存

如何释放?不需要释放,不需要担心内存是否会泄漏,因为只要进程结束,它也能正常释放

http://www.xdnf.cn/news/18584.html

相关文章:

  • 通过python程序将实时监测数据写入excel软件进行保存是常用和非常实用的功能,本文教会大家怎么去搞定此功能
  • 塔能科技物联精准节能如何构建智慧路灯免疫系统
  • pycharm的matplotlib不显示动图问题的解决
  • `free` 内存释放函数
  • Linux --网络基础概念
  • 分布式事务的两种解决方案
  • K8s部署MySQL8.0数据库
  • 【大语言模型 17】高效Transformer架构革命:Reformer、Linformer、Performer性能突破解析
  • Baumer高防护相机如何通过Tiny-YOLO单类模型实现人体跌倒检测与跟踪(C#代码UI界面版)
  • 从 UMG 到 Unreal 引擎深层的 UI 定制艺术:Slate 底层 UI 框架简介
  • Python爬虫-解决在抓包的过程中,找不到接口地址的问题
  • 『深度编码』操作系统-进程之间的通信方法
  • 使用dumpbin指令分析Windows下的PE文件(伍)
  • 跨语言文化的统一语义真理:存在性、形式化及其对自然语言处理(NLP)深层语义分析的影响
  • Transformer实战(13)——从零开始训练GPT-2语言模型
  • Redis--day12--黑马点评--附近商铺用户签到UV统计
  • Trip Footprint_Trae Solo模式生成一个旅行足迹App
  • 【卷积神经网络详解与实例】2——卷积计算详解
  • 大模型训练方法全面解析:SFT、RFT、TRPO、DPO、PPO、GRPO、RLH、RLHF技术深度剖析
  • 14.Shell脚本修炼手册--玩转循环结构(While 与 Until 的应用技巧与案例)
  • 题解:P13754 【MX-X17-T3】Distraction_逆序对_前缀和_Ad-hoc_算法竞赛C++
  • java猜数字游戏(赌城主题版)
  • priority_queue和仿函数
  • 【CSP初赛】程序阅读3
  • (一)算法(big O/)
  • 一种解决使用 PotPlayer 播放 Alist 的 Webdav 时提示 无法在 FTP/WebDAV/HTTP 上修改该文件夹 的方法
  • QT-Mysql-查询语句-查询是否有表-表列名-查询记录
  • 【AI基础:神经网络】16、神经网络的生理学根基:从人脑结构到AI架构,揭秘道法自然的智能密码
  • TensorFlow 深度学习 开发环境搭建
  • Java和数据库的关系