三、定长内存池

三、定长内存池

我们知道申请内存使用的是malloc,malloc其实就是一个通用的大众货,什么场景下都可以使用,而什么场景下都可以用就意味着什么场景下都不会有很高的性能,下面我们就先来设计一个定长内存池作为一个开胃菜,当然这个定长内存池在后面的高并发内存池中也是有价值的,所以学习他目的有两层,第一是先熟悉一下简单内存池是如何控制的,第二是它会作为我们后面内存池的一个基础组件。

在这里插入图片描述

#pragma once#include <iostream>
#include <assert.h>
using std::cout;
using std::endl;#include "Common.h"#ifdef _WIN32
#include <windows.h>
#endif // _WIN32inline static void* SystemAlloc(size_t Kpage)
{
#ifdef _WIN32void* ptr= VirtualAlloc(0, Kpage * (1 << 13), MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);
#else//其他环境
#endif // _WIN32if (ptr == nullptr){throw std::bad_alloc();}return ptr;
}template <class T>
class ObjectPool
{
public:T* New(){T* obj = nullptr;//如果在自由链表中有还回来的内存块,则优先使用if (_freeList != nullptr){//从_freeList链表头删一个内存块,顺便返回//_freeList指向的是自由链表的头上的小对象,这个小对象//的前4个或者8个字节(看机器环境)存放着下一个小对象的地址//*(void**)就拿到了下一个小对象的地址void* next = *(void**)_freeList;//取_freeList自由链表的头上T类型大小个字节赋值给obj即可obj = (T*)_freeList;//把_freeList更新为next相当于在_freeList中头删一个小对象_freeList = next;}else{//如果剩余的内存不够一个对象的大小,则需要重新向堆申请内存if (_RemainBytes < sizeof(T)){_RemainBytes = 128 * 1024;//_memory = (char*)malloc(_RemainBytes);//按页为单位向堆申请内存,一页8k,1k是1024字节,所以一页是2^13次方字节//所以字节数_Remaintypes右移13位就得到页数//直接调用系统调用接口SystemAlloc向堆申请内存,使它完全脱离开malloc函数_memory = (char*)SystemAlloc(_RemainBytes >> 13);if (_memory == nullptr){//申请内存失败就抛异常throw std::bad_alloc();}}//在_memory中切一个T类型大小的对象给objobj = (T*)_memory;//如果T的的大小太小的话就要多给一点内存,使它拥有能够放下一个指针变量大小的空间size_t objSize = sizeof(T) > sizeof(void*) ? sizeof(T) : sizeof(void*);//切走了一块空间就要使地址+=一个对象大小_memory += objSize;//剩余的字节数也要-=一个对象的大小_RemainBytes -= objSize;}//对已有的内存,利用定位new调用T的默认构造函数初始化new(obj)T;return obj;}void Delete(T* obj){//显式调用T的析构函数清理还回来的内存块的资源obj->~T();//把还回来的内存块头插到自由链表中*(void**)obj = _freeList;_freeList = obj;}
private:char* _memory = nullptr;//向堆申请的大块内存void* _freeList = nullptr;//用完之后还回来的内存块连接而成的自由链表size_t _RemainBytes = 0;//申请的大块内存用过之后剩余的字节数
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/62642.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux字符串处理

目录 1. C 截取字符串,截取两个子串中间的字符串linux串口AT指令 2. 获取该字符串后面的字符串用 strstr() 函数查找需要提取的特定字符串&#xff0c;然后通过指针运算获取该字符串后面的字符串用 strtok() 函数分割字符串&#xff0c;找到需要提取的特定字符串后&#xff0c;…

简单使用_matlab生成数据帧

文章目录 生成数据帧参考 生成数据帧 代码如下&#xff0c;代码很简单&#xff0c;有几点要注意&#xff0c; 较高版本的MATLAB中支持0x的写法使用bitand进行位运算使用strcat函数进行字符串拼接时&#xff0c;如果需要插入空格&#xff0c;要使用双引号 cmd_ay(1) 0x33; …

硬件性能评估指标-DMIPS、MFLOPS、MAC、TOPS

硬件性能评估指标-DMIPS、MFLOPS、MAC、TOPS DMIPS&#xff08;Dhrystone Million Instructions Per Second&#xff09;&#xff1a; DMIPS用于衡量计算机系统的整体指令执行性能&#xff0c;通常关注整数操作。它基于Dhrystone基准测试来计算&#xff0c;该测试主要包含整数运…

需求管理系统大盘点,谁能问鼎行业王者宝座?

“需求管理系统有哪些&#xff1f;这些品牌引领行业新风潮&#xff1a;Zoho Projects、SAP SuccessFactors、Oracle NetSuite、Microsoft Dynamics 365、Infor CloudSuite、JDA Software。” 需求管理系统是一种专门用于收集、分析和跟踪客户需求的工具&#xff0c;可以帮助企业…

总线:特性、分类、性能指标、系统总线的结构、总线仲裁、总线定时、总线标准

总线&#xff08;Bus&#xff09;&#xff0c;是一组为各功能部件之间进行信息传送的公共线路。 总线的特性&#xff1a; 机械特性&#xff08;物理特性&#xff09;&#xff1a;尺寸、形状、引脚数、排列顺序。电气特性&#xff1a;每根信号线上的信号传输方向、表示信号有效…

Go实现LogAgent:海量日志收集系统【上篇——LogAgent实现】

Go实现LogAgent 项目架构图&#xff1a; 0 项目背景与方案选择 背景 当公司发展的越来越大&#xff0c;业务越来越复杂时&#xff0c;每个业务系统都有自己的日志。此时我们就应该将不同业务线的日志进行实时收集&#xff0c;存储到一个日志收集中心&#xff0c;最后再通过…

RecyclerView的局部刷新居然这么简单

RecyclerView的局部刷新 面试时经常被问到Android列表控件RecyclerView&#xff0c;无非就是深入源码与ListView进行对比&#xff0c;四层缓存和局部刷新。而今天的重点就是局部刷新 使用场景 我们在使用RecyclerView的局部刷新时&#xff0c;往往使用notify相关方法&#xff…

Android studio 软件git使用

在 test 分支添加的方法 , 现在切换到 master分支 总共 2 个分支 , 当前的分支是 test 出现了 先试一下 force checkout , 尝试之后发现 , 你更改没有带过来 , 以为哪个类在master分支没有 , 所以这边也没有 , 切回分支 test 发现之前的跟改没有 , 这样即可以找回 继续切换…

MySQL—MySQL主从如何保证强一致性

一、前言 涉及到的东西&#xff1a;两阶段提交&#xff0c;binlog三种格式 1、两阶段提交 在持久化 redo log 和 binlog 这两份日志的时候&#xff0c;如果出现半成功的状态&#xff0c;就会造成主从环境的数据不一致性。这是因为 redo log 影响主库的数据&#xff0c;binlog…

python爬虫—requests

一、安装 pip install requests 二、基本使用 1、基本使用 类型 &#xff1a; models.Response r.text : 获取网站源码 r.encoding &#xff1a;访问或定制编码方式 r.url &#xff1a;获取请求的 url r.content &#xff1a;响应的字节类型 r.status_code &#xff1a;响应…

界面控件DevExpress WinForms(v23.2)下半年发展路线图

本文主要概述了官方在下半年&#xff08;v23.2&#xff09;中一些与DevExpress WinForms相关的开发计划&#xff0c;重点关注的领域将是可访问性支持和支持.NET 8。 DevExpress WinForms有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。同时能…

数据库访问性能优化

目录 IO性能分析数据库性能优化漏斗法则1、减少数据访问&#xff08;减少磁盘访问&#xff09;(1) 正确的创建并使用索引索引生效场景索引失效场景判断索引是否生效--执行计划 2、返回更少数据&#xff08;减少网络传输或磁盘访问&#xff09;(1) 数据分页处理(减少行数)客户端…

字符和字符串的库函数模拟与实现

前言&#xff1a; 相信大家平常在写代码的时候&#xff0c;用代码解决实际问题时苦于某种功能的实现&#xff0c;而望而止步&#xff0c;这个时候库函数的好处就体现出来了&#xff0c;当然个人代码编写能力强的可以自己创建一个函数&#xff0c;不过相当于库函数来说却是浪费了…

Redis进阶 - JVM进程缓存

原文首更地址&#xff0c;阅读效果更佳&#xff01; Redis进阶 - JVM进程缓存 | CoderMast编程桅杆https://www.codermast.com/database/redis/redis-advance-jvm-process-cache.html 传统缓存的问题 传统的缓存策略一般是请求到达 Tomcat 后&#xff0c;先查询 Redis &…

Java文件操作

目录 一、File类概述 1.1 使用案例 二、文件内容的读写 2.1 字符流 2.1.1 读取文件 2.1.2 写入文件 2.2 字节流 2.2.1 读取文件 2.2.2 写入文件 对于Java操作文件&#xff0c;具体详情可以参考Java api文档 中的Java.io.File类 一、File类概述 首先先了解一下File类中常见的属…

Unity 从2018升级为2021之后 IAP(内购插件)报错解决

从老项目升级为2021高版本之后报了个错 大概就是… the type iwindowsiap exists in both unityengine.purchasing.winrtcore, version0.0.0.0, 这种 具体的我也没粘贴全部过来 原因貌似是 PackManger里面的IPA包和项目自带的冲突了 解决方法&#xff1a; 删除项目文件夹下面…

leetcode3. 无重复字符的最长子串(滑动窗口 - java)

滑动窗口 无重复字符的最长子串滑动窗口 上期经典 无重复字符的最长子串 难度 - 中等 3. 无重复字符的最长子串 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc…

代码随想录算法训练营第五十二天 | 300.最长递增子序列,674. 最长连续递增序列,718. 最长重复子数组

代码随想录算法训练营第五十二天 | 300.最长递增子序列&#xff0c;674. 最长连续递增序列&#xff0c;718. 最长重复子数组 300.最长递增子序列674. 最长连续递增序列718. 最长重复子数组 300.最长递增子序列 题目链接 视频讲解 给你一个整数数组 nums &#xff0c;找到其中最…

JDK源码解析-LinkedList

1. LinkedList类 1.1 LinkedList类定义&数据结构 定义 LinkedList是一种可以在任何位置进行高效地插入和移除操作的有序序列&#xff0c;它是基于双向链表实现的。 数据结构 基础知识补充 单向链表&#xff1a; element&#xff1a;用来存放元素 next&#xff1a;用来…

SpringBoot项目(jar)部署,启动脚本

需求 SpringBoot项目&#xff08;jar&#xff09;部署&#xff0c;需要先关闭原来启动的项目&#xff0c;再启动新的项目。直接输入命令&#xff0c;费时费力&#xff0c;还容易出错。所以&#xff0c;使用脚本启动。 脚本 脚本名&#xff1a;start.sh 此脚本需要放置在jar包…