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

【Buffer Pool】定长内存池的实现

创建一个大块的内存内存

1.内存的类型是什么? char*  方便有多少字节就乘以多少字节

2.如何还回来内存?可以将换回来的小块的内存块链接起来,使用freeList

3.如何链接起来? 让上一个内存块的数据存下一个内存块的地址即可

4.如果内存块的定长大小为20字节,该如何存储地址呢? 如果是32位下,指针大小为4字节,就划分内存的前4字节的空间存储地址。如果是64位下,就划分前8字节的空间存储地址。

5.如果内存块的定长大小不足4字节获得8字节呢?

6.如果没有剩余空间了,如何判断?  使用成员变量remainBytes,表示大块内存剩余的空间

7.第一次还回来了一个对象(内存),该怎么处理?让内存块头4字节或者8字节(一个指针的大小)指向空   

     7.1如何判断环境是32位还是64位?  对类型指针就行了,void是类型,void*是void的指针

*(void**)等于void*(对void*指针再解引用,为什么要这么写?因为这样写可以对该对象进行写入了),void*是指针类型,大小就是指针的大小

8.刚刚解决了第一次还回来的问题,那第二次第三次呢?   可以头插

并且,第一次和第二次是相同的,头插都可以解决

9.有没有一种可能性,大内存块切了一部分,同时又有一部分内存还回来了,这时候接下来如果要继续申请内存,该怎么处理呢?是用原来的大内存块继续切还是用还回来的内存呢?

全部代码:

#pragma once
#include<iostream>
#include<vector>
#include<time.h>
using std::cout;
using std::endl;template<class T>
class ObjectPool
{
public://申请内存T* New(){T* obj = nullptr;//1.优先把换回来的内存块再次重复利用if (_freeList)  //代表有还回来的内存块对象{//重复利用,进行单链表的头删 //这里的*(void**)_freeList表示取freeLiset的前指针大小个字节 -->也就是取next的地址void* next = *((void**)_freeList);     //?  这里为什么使用void**//obj是取整个对象obj = (T*)_freeList;//往后移动一位_freeList = next;}else  //如果没有还回来的内存块{//判断开辟的一大块空间是否够这次申请的if (_remainBytes < sizeof(T))  {//如果不够_remainBytes = 1024 * 128;   //申请128KB//这里为什么要这么写?_memory = (char*)malloc(_remainBytes);//SystemAlloc是系统调用接口//_memory = (char*)SystemAlloc(_remainBytes >> 13);//异常处理if (_memory == nullptr){throw std::bad_alloc();}}//创建一个对象指向memory,这个obj也就是我们申请内存给到的实体obj = (T*)_memory;//这里判断的意义是:如果我们申请的空间大于指针的大小,就返回我们申请的空间,//否则返回指针的大小  --> 这样做是为了内存块至少能存下地址size_t objSize = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);//大块内存的指针向后移动_memory += objSize;//可用空间减少_remainBytes -= objSize;}new(obj) T;return obj;}//这是释放的过程,将释放的小内存块挂到_freeList前面void Delete(T* obj){//显式调用函数清理对象obj->~T();//头插//将obj内存块的前指针大小的字节存入_freeList的地址*(void**)obj = _freeList;//将_freeList移动为头结点_freeList = obj;}
private:char* _memory = nullptr;         //指向大块内存的指针size_t _remainBytes = 0;         //大块内存切分过程中剩余字节数void* _freeList = nullptr;      //还回来过程中链接的滋有链表的头指针
};//测试
struct TreeNode
{int _val;TreeNode* _left;TreeNode* _right;TreeNode():_val(0), _left(nullptr), _right(nullptr){}
};void TestObjectPool()
{// 申请释放的轮次const size_t Rounds = 5;// 每轮申请释放多少次const size_t N = 100000;std::vector<TreeNode*> v1;v1.reserve(N);size_t begin1 = clock();for (size_t j = 0; j < Rounds; ++j){for (int i = 0; i < N; ++i){v1.push_back(new TreeNode);}for (int i = 0; i < N; ++i){delete v1[i];}v1.clear();}size_t end1 = clock();std::vector<TreeNode*> v2;v2.reserve(N);ObjectPool<TreeNode> TNPool;size_t begin2 = clock();for (size_t j = 0; j < Rounds; ++j){for (int i = 0; i < N; ++i){v2.push_back(TNPool.New());}for (int i = 0; i < N; ++i){TNPool.Delete(v2[i]);}v2.clear();}size_t end2 = clock();cout << "系统自带的new cost time:" << end1 - begin1 << endl;cout << "定长内存池的object pool cost time:" << end2 - begin2 << endl;
}

运行结果:debug模式

release模式:

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • cmake(1)
  • 【C++】:错误处理机制 -- 异常
  • 图像处理案例02
  • 效率何止10倍!利用输入法瞬间调用提示词
  • Harmony OS 卡片能力
  • ARM 离线安装k8s + harbor私有镜像库(麒麟)
  • NLP 之词的表示与语言模型
  • 巴黎奥运会8K转播科技为国产品牌自主研发设计
  • 第二章 部署LVS-DR集群
  • Mongodb权限
  • 谷粒商城实战笔记-136-商城业务-首页-整合thymeleaf渲染首页
  • Django异步请求和后台管理实战
  • 『哈哥赠书 - 55期』-『码农职场:IT人求职就业手册』
  • IT课程学习搭子
  • 【AD域】搭建AD域服务器
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • Date型的使用
  • Docker: 容器互访的三种方式
  • echarts花样作死的坑
  • Java IO学习笔记一
  • Javascripit类型转换比较那点事儿,双等号(==)
  • js数组之filter
  • SegmentFault 2015 Top Rank
  • spring boot 整合mybatis 无法输出sql的问题
  • Sublime Text 2/3 绑定Eclipse快捷键
  • 爱情 北京女病人
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 反思总结然后整装待发
  • 给第三方使用接口的 URL 签名实现
  • 技术发展面试
  • 简单数学运算程序(不定期更新)
  • 离散点最小(凸)包围边界查找
  • 浅谈JavaScript的面向对象和它的封装、继承、多态
  • 悄悄地说一个bug
  • 区块链共识机制优缺点对比都是什么
  • 思否第一天
  • 思维导图—你不知道的JavaScript中卷
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 小而合理的前端理论:rscss和rsjs
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • ​业务双活的数据切换思路设计(下)
  • # 详解 JS 中的事件循环、宏/微任务、Primise对象、定时器函数,以及其在工作中的应用和注意事项
  • #使用清华镜像源 安装/更新 指定版本tensorflow
  • (4)事件处理——(7)简单事件(Simple events)
  • (70min)字节暑假实习二面(已挂)
  • (ibm)Java 语言的 XPath API
  • (NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!
  • (poj1.3.2)1791(构造法模拟)
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (二)pulsar安装在独立的docker中,python测试
  • (力扣题库)跳跃游戏II(c++)