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

C++的allactor

https://zhuanlan.zhihu.com/p/693267319

1 双层内存配置器

SGI设计了两层的配置器,也就是第一级配置器和第二级配置器。同时为了自由选择,STL又规定了 __USE_MALLOC 宏,如果它存在则直接调用第一级配置器,不然则直接调用第二级配置器。SGI未定义该宏,也就是说默认使用第二级配置器。

1.1 一级内存配置器

直接调用malloc和free来配置释放内存,简单明了。

template<int Inst>
class __MallocAllocTemplate //一级空间配置器
{typedef void (*OOM_HANDLER)();
private://these funs below are used for "OOM" situations//OOM = out of memorystatic void* OOM_Malloc(size_t n); //functionstatic void* OOM_Realloc(void *p, size_t newSZ); //functionstatic OOM_HANDLER OOM_Handler; //function pointerpublic:static void* Allocate(size_t n){void* ret = malloc(n);if (ret == NULL)ret = OOM_Malloc(n);return ret;}static void Deallocate(void* p, size_t n){free(p);}static void* Reallocate(void* p, size_t oldSZ, size_t newSZ){void* ret = realloc(p, newSZ);if (ret == NULL)ret = OOM_Realloc(p, newSZ);return ret;}//static void (* set_malloc_handler(void (*f)()))()//参数和返回值都是函数指针void (*)()static OOM_HANDLER SetMallocHandler(OOM_HANDLER f){OOM_HANDLER old = OOM_Handler;OOM_Handler = f;return old;}
};//让函数指针为空
template<int Inst>
void (*__MallocAllocTemplate<Inst>::OOM_Handler)() = NULL;template<int Inst>
void* __MallocAllocTemplate<Inst>::OOM_Malloc(size_t n)
{void* ret = NULL;void(*myHandler)() = NULL;for (;;){myHandler = OOM_Handler;if (myHandler == NULL)throw bad_alloc();(*myHandler)();ret = malloc(n);if (ret != NULL)return ret;}
}template<int Inst>
void* __MallocAllocTemplate<Inst>::OOM_Realloc(void* p, size_t newSZ)
{void* ret = NULL;void(*myHandler)() = NULL;for (;;){myHandler = OOM_Handler;if (myHandler == NULL)throw bad_alloc();(*myHandler)();ret = realloc(p, newSZ);if (ret != NULL)return ret;}
}typedef __MallocAllocTemplate<0> MallocAlloc; //一级空间配置重命名

1.2 二级内存配置器

1.如果用户需要的区块大于128,则直接调用第一级空间配置器
2.如果用户需要的区块大于128,则到自由链表中去找

  • 如果自由链表有,则直接去取走
  • 不然则需要装填自由链表(Refill)

1.2.1 自由链表

在这里插入图片描述
自由链表是一个指针数组,它的数组大小为16,每个数组元素代表所挂的区块大小,比如free _ list[0]代表下面挂的是8bytes的区块,free _ list[1]代表下面挂的是16bytes的区块…….依次类推,直到free _ list[15]代表下面挂的是128bytes的区块

同时我们还有一个被称为内存池地方,以start _ freeend _ free记录其大小,用于保存未被挂在自由链表的区块,它和自由链表构成了伙伴系统。

1.2.2 工作原理

如果用户需要是一块n字节的区块,且n <= 128(调用第二级配置器),此时Refill填充是这样的:

  • 系统会自动将n字节扩展到8的倍数,再将RoundUP(n)传给Refill
  • 用户需要n字节,且自由链表中没有,因此系统会向内存池申请nobjs * n大小的内存块,默认nobjs=20
  • 如果内存池大于 nobjs * n,那么直接从内存池中取出
  • 如果内存池小于nobjs * n,但是比一块大小n要大,那么此时将内存最大可分配的块数给自由链表,并且更新nobjs为最大分配块数x (x < nobjs)
  • 如果内存池连一个区块的大小n都无法提供,那么首先先将内存池残余的零头给挂在自由链表上,然后向系统heap申请空间,申请成功则返回,申请失败则到自己的自由链表中看看还有没有可用区块返回
  • 如果连自由链表都没了最后会调用一级配置器。

3 自定义内存配置器

// TODO:为vector写一个内存配置器,当空间大于1000时直接从堆分配内存#include <memory>
#include <vector>
#include <iostream>// 自定义内存配置器
template <typename T>
class CustomAllocator : public std::allocator<T> {
public:// 分配内存T* allocate(std::size_t n) {if (n * sizeof(T) > 1000) {// 大于1000字节时,使用堆分配return static_cast<T*>(::operator new(n * sizeof(T)));} else {// 小于或等于1000字节时,使用默认分配return std::allocator<T>::allocate(n);}}// 释放内存void deallocate(T* p, std::size_t n) {if (n * sizeof(T) > 1000) {// 大于1000字节时,使用堆释放::operator delete(p);} else {// 小于或等于1000字节时,使用默认释放std::allocator<T>::deallocate(p, n);}}
};int main() {// 使用自定义内存配置器的vectorstd::vector<int, CustomAllocator<int>> vec;vec.push_back(1); // 应该使用默认分配方式(通常很小)vec.push_back(2); // 同上vec.resize(1024); // 应该使用堆分配方式(因为1024 * sizeof(int) > 1000)vec.resize(1); // 应该再次使用默认分配方式(因为1 * sizeof(int) <= 1000)return 0;
}

相关文章:

C++的allactor

https://zhuanlan.zhihu.com/p/693267319 1 双层内存配置器 SGI设计了两层的配置器&#xff0c;也就是第一级配置器和第二级配置器。同时为了自由选择&#xff0c;STL又规定了 __USE_MALLOC 宏&#xff0c;如果它存在则直接调用第一级配置器&#xff0c;不然则直接调用第二级配…...

【2025深度学习环境搭建-2】pytorch+Docker+VS Code+DevContainer搭建本地深度学习环境

上一篇文章&#xff1a;【2025深度学习环境搭建-1】在Win11上用WSL2和Docker解锁GPU加速 先启动Docker&#xff01;对文件内容有疑问&#xff0c;就去问AI 一、用Docker拉取pytorch镜像&#xff0c;启动容器&#xff0c;测试GPU docker pull pytorch/pytorch:2.5.0-cuda12.4…...

在CentOS 7上安装和使用Spleeter音频分离工具的详细步骤

在音频处理领域&#xff0c;Spleeter是一款优秀的开源工具&#xff0c;能够帮助用户轻松实现音频文件中人声和背景音的分离。本文将详细介绍在CentOS 7系统上安装和配置Spleeter的步骤&#xff0c;以及如何使用Spleeter进行音频分离。 准备环境: 在开始安装Spleeter之前&…...

【1】VS Code 新建上位机项目---C#基础语法

VS Code 新建上位机项目---C#基础语法 1 基本概念1.1 准备工具1.2 新建项目2 C#编程基础2.1 命名空间和类2.2 数据类型2.3 控制台输入输出2.3.1 输入输出: write 与 read2.3.2 格式化 : string.Foramt() 与 $2.3.3 赋值与运算2.4 类型转换2.4.1 数值类型之间的转换:(int)2.4…...

电脑经常绿屏(蓝屏)怎么办(解决方法)?

一、排查系统与驱动问题 进入安全模式修复系统 强制重启电脑 3 次触发恢复环境&#xff0c;选择 疑难解答 > 高级选项 > 启动设置 > 重启&#xff0c;按 F5 或 5 进入带网络连接的安全模式3。 在安全模式下&#xff0c;尝试卸载最近安装的软件或更新&#xff0c;尤其…...

clickhouse--本地表和分布式表,副本机制,分片集群

1、本地表和分布式表 ck的表分为两种: 分布式表   一个逻辑上的表&#xff0c;可以理解为数据库中的视图&#xff0c;一般查询都查询分布式表。分布式表引擎会将我们的查询请求路由本地表进行查询&#xff0c;然后进行汇总最终返回给用户。本地表   实际存储数据的表。 …...

react hook useReducer

useReducer useReducer 是 React 中用于状态管理的 Hook&#xff0c;与 useState 不同&#xff0c;它更适合处理复杂的状态逻辑. const [state, dispatch] useReducer(reducer, initialArg, init?) reducer 是一个处理函数&#xff0c;用于更新状态, reducer 里面包含了两个…...

告别阻塞,迎接高效:掌握 AsyncIOScheduler 实现异步任务调度

前言 时间在编程中是宝贵的,直接关联到效率与灵活性,尤其在异步编程里,如何优雅地管理定时任务简直是一门“艺术”。如果你还在用 time.sleep() 来控制延时任务,恐怕你早已体会过它的“痛苦”:程序卡住、线程阻塞、性能急剧下滑。想象一下,你的程序如同一个永远无法按时…...

【基于SprintBoot+Mybatis+Mysql】电脑商城项目之加入购物车和显示购物车列表

&#x1f9f8;安清h&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;【Spring篇】【计算机网络】【Mybatis篇】 &#x1f6a6;作者简介&#xff1a;一个有趣爱睡觉的intp&#xff0c;期待和更多人分享自己所学知识的真诚大学生。 目录 &#x1f680;1.加入购物车-数…...

再谈影刀RPA成长学习路线

近期&#xff0c;我将使用影刀RPA开发各电商平台移动端商品信息爬取,实战流程会在QQ群里分享&#xff0c;欢迎大家进群&#xff0c;一起探讨交流&#xff01; 1. 影刀RPA学习路线概述 1.1 学习目标与意义 学习影刀RPA的目标在于掌握一种高效的工作自动化工具&#xff0c;以提…...

PHP-综合4

[题目信息]&#xff1a; 题目名称题目难度PHP-综合42 [题目考点]&#xff1a; PHP综合训练[Flag格式]: SangFor{Ouk3i63BuShgxqdRcn_9kMNqKFDe5j4f}[环境部署]&#xff1a; docker-compose.yml文件或者docker tar原始文件。 http://分配ip:2087[题目writeup]&#xff1a;…...

学习笔记-沁恒第五讲-米醋

一&#xff0c;设置音量 上次 这次 #include "uart.h" #include "debug.h" void audio_init() { Usart3_Init(); } void audio_play(u8 num) { u8 string[]{0x7e,0x05,0x41,0x00,num,0x05^0x41^0x00^num,0xef}; u8 i; for(i0;i<7;i) { USART_Se…...

【JavaScript】JavaScript 常见概念 - 变量与数据类型 - 运算符 - 条件语句 - 循环 - 函数 - 数组操作 - 对象

1. 变量与数据类型 变量声明 JavaScript 提供了三种方式来声明变量&#xff1a; var&#xff08;全局或函数作用域&#xff0c;不推荐&#xff09;let&#xff08;块级作用域&#xff0c;推荐&#xff09;const&#xff08;常量&#xff0c;块级作用域&#xff0c;推荐&…...

Web自动化之Selenium添加网站Cookies实现免登录

在使用Selenium进行Web自动化时&#xff0c;添加网站Cookies是实现免登录的一种高效方法。通过模拟浏览器行为&#xff0c;我们可以将已登录状态的Cookies存储起来&#xff0c;并在下次自动化测试或爬虫任务中直接加载这些Cookies&#xff0c;从而跳过登录步骤。 Cookies简介 …...

AI手机的技术细节

前序&#xff1a;先说各个功能涉及到的技术&#xff0c;再说宏观系统架构。AI手机有这样几个做法&#xff0c;给手机侧边增加一个按键&#xff1b;把手机的语音助手做的很好&#xff0c;能够快速稳定的进行唤醒&#xff1b;通过特殊形式的触摸手机的曲面屏位置等来进行唤醒AI …...

10. 九转金丹炼矩阵 - 矩阵置零(标记优化)

哪吒在数据修仙界中继续他的修炼之旅。这一次,他来到了一片神秘的金丹谷,谷中有一座巨大的九转金丹炉,炉身闪烁着神秘的光芒。金丹炉的入口处有一块巨大的石碑,上面刻着一行文字:“欲破此炉,需以九转金丹之力,炼矩阵之零,标记优化定乾坤。” 哪吒定睛一看,石碑上还有…...

[实现Rpc] 客户端 | Requestor | RpcCaller的设计实现

目录 Requestor类的实现 框架 完善 onResponse处理回复 完整代码 RpcCaller类的实现 1. 同步调用 call 2. 异步调用 call 3. 回调调用 call Requestor类的实现 &#xff08;1&#xff09;主要功能&#xff1a; 客户端发送请求的功能&#xff0c;进行请求描述对服务器…...

Java 大视界 -- 深度洞察 Java 大数据安全多方计算的前沿趋势与应用革新(52)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

山东大学软件学院nosql实验三

实验题目&#xff1a; 用Java做简单查询(2学时) 实验内容 用API方式&#xff0c;做简单查询。 实验要求 在以下要求中选择至少2个&#xff0c;使用Java语言实现数据查询&#xff0c;最终把数据输出到前端界面。 &#xff08;1&#xff09;找出年龄小于20岁的所有学生 &…...

正态分布的奇妙性质:为什么奇数阶中心矩(odd central moments)为零?

正态分布的奇妙性质&#xff1a;为什么奇数阶矩为零&#xff1f; 正态分布&#xff08;Normal Distribution&#xff09;是统计学中最常见的分布之一&#xff0c;它的钟形曲线几乎无处不在&#xff0c;从身高体重到测量误差&#xff0c;都能看到它的影子。除了均值和方差这两个…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...