当前位置: 首页 > 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;都能看到它的影子。除了均值和方差这两个…...

Calibre豆瓣插件:智能获取图书元数据的终极解决方案

Calibre豆瓣插件&#xff1a;智能获取图书元数据的终极解决方案 【免费下载链接】calibre-douban Calibre new douban metadata source plugin. Douban no longer provides book APIs to the public, so it can only use web crawling to obtain data. This is a calibre Douba…...

2026年降AI率工具排行榜怎么选?3招避开智商税

2026年毕业季一到&#xff0c;朋友圈、知乎、小红书上铺天盖地的"降AI率工具排行榜"就开始刷屏。今天这家说"全网第一"&#xff0c;明天那家又"权威评测"&#xff0c;榜单的前三名永远在换人。我帮三届学弟学妹选过工具,也自己踩过不少坑,今天就…...

别再为VSCode里Python的import报错抓狂了!一个dev.env文件搞定所有路径问题

VSCode中Python项目路径管理的终极解决方案 每次在VSCode中打开Python项目&#xff0c;看到那些红色的波浪线和"ModuleNotFoundError"错误提示&#xff0c;是不是感觉特别烦躁&#xff1f;作为一个长期在VSCode中开发Python项目的工程师&#xff0c;我完全理解这种痛…...

Multisim元件库深度解析:从虚拟器件到真实元件的实战指南

1. Multisim元件库的核心分类与设计哲学 第一次打开Multisim的元件库时&#xff0c;那种扑面而来的压迫感我至今记忆犹新——就像走进了一个巨大的电子元器件超市&#xff0c;货架上密密麻麻摆着上万种元件。但经过多年教学实践&#xff0c;我发现这些元件本质上可以分为两大阵…...

如何在 Go 中安全高效地比较两个 map 的对应值

本文介绍如何遍历 map[string]float64 并基于共享键安全比较两 map 中的浮点数值&#xff08;如 m1[k]/m2[k] > 1&#xff09;&#xff0c;重点解决零值访问、键缺失和除零风险等常见陷阱。 本文介绍如何遍历 map[string]float64 并基于共享键安全比较两 map 中的浮点数…...

Bilibili评论爬虫:如何轻松获取B站视频的完整评论数据?[特殊字符]

Bilibili评论爬虫&#xff1a;如何轻松获取B站视频的完整评论数据&#xff1f;&#x1f680; 【免费下载链接】BilibiliCommentScraper B站视频评论爬虫 Bilibili完整爬取评论数据&#xff0c;包括一级评论、二级评论、昵称、用户ID、发布时间、点赞数 项目地址: https://git…...

高效PCK文件逆向工程:GDSDecomp工具深度解析与实战指南

高效PCK文件逆向工程&#xff1a;GDSDecomp工具深度解析与实战指南 【免费下载链接】gdsdecomp Godot reverse engineering tools 项目地址: https://gitcode.com/GitHub_Trending/gd/gdsdecomp 在Godot游戏开发与逆向工程领域&#xff0c;PCK文件处理一直是一个技术难点…...

Open Event Frontend 移动端适配与响应式设计:打造完美跨平台体验

Open Event Frontend 移动端适配与响应式设计&#xff1a;打造完美跨平台体验 【免费下载链接】open-event-frontend The frontend for the Open Event API Server https://test.eventyay.com 项目地址: https://gitcode.com/gh_mirrors/op/open-event-frontend Open Ev…...

终极指南:如何用gmx_MMPBSA轻松计算蛋白质-配体结合自由能

终极指南&#xff1a;如何用gmx_MMPBSA轻松计算蛋白质-配体结合自由能 【免费下载链接】gmx_MMPBSA gmx_MMPBSA is a new tool based on AMBERs MMPBSA.py aiming to perform end-state free energy calculations with GROMACS files. 项目地址: https://gitcode.com/gh_mirr…...

优雅地使用MUI组件:去除最后一个分隔线

在使用Material-UI(MUI)组件开发用户界面时,我们经常需要对菜单或列表进行分组,并在每个分组之间添加一个分隔线以增强视觉区分度。然而,有时我们不希望在最后一个分组后添加分隔线,因为这会显得多余。今天我们将探讨如何在MUI中实现这种需求,确保UI的清洁和美观。 背景…...