c++(空间配置器)[32]

news2024/9/22 15:49:49

空间配置器

在这里插入图片描述
在这里插入图片描述

一级空间配置器 || 二级空间配置器

在这里插入图片描述
默认先走二级然后判断

二级空间配置器

在这里插入图片描述
一个指针指向start_free然后start_free向后移动,相当于哈希桶的头删和头插
在这里插入图片描述
8byte:切大补小
C++的二级空间配置器按照8字节(或者更大的倍数)切分内存的原因有以下几点:

  1. 内存对齐:许多计算机体系结构要求数据在内存中的地址是对齐的,即数据的起始地址必须是某个特定值的倍数。按照8字节切分内存可以确保分配的内存块的起始地址满足对齐要求,从而提高内存访问的效率。

  2. 减少内存碎片:内存碎片是指分配的内存块之间存在的未使用的小块内存。通过按照8字节切分内存,可以减少内存碎片的产生。如果按照较小的单位(如1字节)切分内存,会导致更多的内存碎片,降低内存的利用率。

  3. 提高内存分配的效率:按照8字节切分内存可以提高内存分配的效率。二级空间配置器使用了一些数据结构(如自由链表)来管理内存池,按照固定大小的块进行切分可以简化数据结构的设计和操作,从而提高内存分配的速度。

需要注意的是,按照8字节切分内存并不是绝对的规定,具体的实现可能会根据不同的编译器、操作系统和硬件平台进行调整。但按照8字节切分内存是比较常见的做法,可以在大多数情况下获得较好的性能和内存利用率。

好的,我来具体解释一下被还回来的小空间是如何被申请的大空间利用的过程。以下是一个简化的示意图:

+-----------------------+
|         大空间         |
+-----------------------+
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
+-----------------------+
  1. 初始状态:大空间被划分为多个小空间,每个小空间的状态为已分配或未分配。
+-----------------------+
|         大空间         |
+-----------------------+
|   |   |   |   |   |   |
|   | A |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
+-----------------------+
  1. 释放小空间:当程序不再需要某个小空间时,将其释放回内存池。
+-----------------------+
|         大空间         |
+-----------------------+
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
+-----------------------+
  1. 标记小空间为可用:二级空间配置器会将被释放的小空间标记为可用。
+-----------------------+
|         大空间         |
+-----------------------+
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
+-----------------------+
  可用   可用   可用
  1. 分配大空间:当程序需要申请大空间时,二级空间配置器会查找可用的连续小空间。
+-----------------------+
|         大空间         |
+-----------------------+
|   |   |   |   |   |   |
|   | A |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
+-----------------------+
  1. 标记小空间为已分配:二级空间配置器会将被分配的小空间标记为已分配,并从内存池中移除。
+-----------------------+
|         大空间         |
+-----------------------+
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
+-----------------------+

通过这个过程,被还回来的小空间可以被申请的大空间利用,从而实现内存的高效利用。

需要注意的是,实际的内存管理过程可能更加复杂,涉及到内存碎片的合并、内存池的扩展等操作。上述示意图仅用于说明基本的内存分配和释放过程。

不是所有进程都公用一个空间配置器。在操作系统中,每个进程都有自己独立的虚拟地址空间,这意味着每个进程都有自己的内存管理单元。

每个进程的内存管理单元负责管理该进程的内存分配和释放。这包括将进程所需的内存从操作系统中分配出来,并在进程不再需要时将其释放回操作系统。

因此,每个进程都有自己的空间配置器,用于管理其内存分配和释放。这样可以确保每个进程的内存操作互不干扰,提高了系统的安全性和稳定性。

需要注意的是,不同进程之间可以通过进程间通信的机制共享内存,但共享的内存通常是通过特殊的方式进行管理,而不是直接使用一个公用的空间配置器。

碎片(一部分一部分还)
空间配置器的碎片指的是内存中的小块未被使用的空间,这些空间可能散落在已分配的内存块之间,无法被有效利用。为了解决内存碎片的问题,空间配置器通常会采取合并碎片的策略。

具体来说,当一个内存块被释放回空间配置器时,空间配置器会尝试将其与相邻的空闲内存块进行合并,以形成更大的连续空闲内存块。这个过程称为内存碎片的合并。

合并碎片的策略可以有多种实现方式,以下是一种常见的策略:

  1. 首次适应(First Fit):空间配置器会从内存池中的第一个空闲内存块开始遍历,找到第一个足够大的空闲内存块来满足分配请求。如果找到了合适的内存块,就将其分割成两部分,一部分用于分配,另一部分保留为新的空闲内存块。

  2. 循环首次适应(Next Fit):类似于首次适应,但是从上一次分配的位置开始遍历内存池,直到找到合适的内存块。这样可以减少遍历的次数。

  3. 最佳适应(Best Fit):空间配置器会遍历整个内存池,找到能够满足分配请求并且大小最接近的空闲内存块。这样可以最大程度地减少内存碎片。

  4. 最坏适应(Worst Fit):空间配置器会遍历整个内存池,找到能够满足分配请求并且大小最大的空闲内存块。这样可以保留更多的小空闲块,但是可能会导致更多的内存碎片。

无论采用哪种策略,合并碎片的目的都是尽可能地利用内存,减少内存碎片的影响。通过合并碎片,空间配置器可以提供更大的连续内存块,从而满足大内存分配的需求。

在这里插入图片描述
解决外碎片问题的方法之一是使用内存池(Memory Pool)或内存池分配器(Memory Pool Allocator)。

内存池是一种预先分配一大块连续内存的数据结构,然后根据需要从该内存池中分配小块内存。内存池可以避免频繁向系统申请小块内存的开销,并且可以减少外碎片的产生。

以下是解决外碎片问题的一种基本思路:

  1. 在程序初始化阶段,分配一大块连续的内存作为内存池。

  2. 将内存池划分为固定大小的小块内存,可以使用链表或位图等数据结构来管理这些小块内存的分配情况。

  3. 当需要申请小块内存时,从内存池中找到一个空闲的小块内存进行分配。

  4. 当小块内存不再使用时,将其标记为空闲,并将其归还到内存池中。

通过使用内存池,可以避免频繁向系统申请小块内存,从而减少了内存碎片的产生。此外,内存池还可以提供连续的内存块,使得可以更容易地申请大块内存。

需要注意的是,使用内存池也会带来一些额外的开销,比如内存池的初始化和管理。因此,在选择是否使用内存池时,需要根据具体的应用场景和需求进行权衡。

STL六大组件

  1. 容器(Containers):STL提供了多种容器类,如vector、list、deque、set、map等。容器类提供了不同的数据结构,用于存储和管理数据。每种容器类都有自己的特点和适用场景,可以根据需要选择合适的容器类。

  2. 算法(Algorithms):STL提供了一组常用的算法,如排序、查找、合并、删除等。这些算法可以应用于各种容器类,提供了高效的实现和使用方式。使用STL算法可以简化编程过程,提高代码的可读性和可维护性。

  3. 迭代器(Iterators):STL提供了迭代器作为容器和算法之间的桥梁。迭代器提供了一种统一的访问容器元素的方式,可以通过迭代器遍历容器中的元素,实现对容器的操作。STL还提供了不同种类的迭代器,如输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器,每种迭代器都有不同的功能和限制。

  4. 仿函数(Functors):STL中的仿函数是一种可调用对象,类似于函数指针,可以在算法中使用。仿函数可以作为算法的参数,用于定义算法的行为。STL提供了一些内置的仿函数,如比较仿函数、数值仿函数等,同时也可以自定义仿函数。

  5. 适配器(Adapters):STL提供了适配器用于修改容器或者算法的接口。适配器可以将一种容器或算法的接口转换为另一种接口,使得它们可以互相兼容。STL中常见的适配器有迭代器适配器、函数适配器等。

  6. 分配器(Allocators):STL提供了分配器用于管理内存的分配和释放。分配器可以为容器提供自定义的内存管理策略,如内存池分配器、堆分配器等。通过分配器,可以控制容器的内存使用方式,提高内存的分配效率和性能。

在这里插入图片描述
在这里插入图片描述

复习

vector:基于动态数组
list:双向链表
set:平衡二叉搜索树(元素唯一)
map:红黑树
unordered_map:基于哈希表(Hash Table)
std::unordered_set:基于哈希表实现,它存储一组无序的唯一元素。std::unordered_set提供了快速的插入、删除和查找操作,平均情况下的时间复杂度为O(1)。

map和unorder_map,set和unorder_set的本质区别

std::mapstd::unordered_mapstd::setstd::unordered_set的本质区别在于它们使用的底层数据结构和提供的操作效率。

  1. std::mapstd::unordered_map的本质区别:
  • std::map基于红黑树实现,它保持了元素的有序性。红黑树是一种自平衡的二叉搜索树,提供了对键的快速查找、插入和删除操作,时间复杂度为O(log n)。std::map中的元素按照键的顺序进行排序,因此可以用作有序的查找表。
  • std::unordered_map基于哈希表实现,它使用键的哈希值来确定元素的存储位置。哈希表提供了快速的插入、删除和查找操作,平均情况下的时间复杂度为O(1)。std::unordered_map中的元素没有固定的顺序,因此不能用作有序的查找表,但它在大多数情况下提供了更快的操作。
  1. std::setstd::unordered_set的本质区别:
  • std::set基于红黑树实现,它存储一组有序的唯一元素。std::set提供了高效的插入、删除和查找操作,时间复杂度为O(log n)。
  • std::unordered_set基于哈希表实现,它存储一组无序的唯一元素。std::unordered_set提供了快速的插入、删除和查找操作,平均情况下的时间复杂度为O(1)。

因此,std::mapstd::set适用于需要有序元素或按照键进行排序的场景,而std::unordered_mapstd::unordered_set适用于对元素顺序没有要求,但需要更快的操作速度的场景。

在这里插入图片描述
在这里插入图片描述
multi版本:允许键值冗余

在这里插入图片描述

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

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

相关文章

《流浪地球3》预告片流出?!网友整活竟被郭导翻牌、央视点赞!

年初《流浪地球2》掀起了一股“科幻热”,而这股热潮直至今日还只增不减。这不,一位名叫“数字生命卡兹克”的博主已经开始“整活”了!他利用AI技术,自制了《流浪地球3》的预告片,并迅速火遍全网。 更牛的是&#xff0c…

apple pencil二代值不值得买?好用的苹果平替笔推荐

自从苹果的Pencil系列问世以来,在国内电容笔市场的销量大增,而苹果的Pencil系列,其的售价更是贵的让人望而却步。现在市面上有很多平替的电容笔,都能取代苹果的Pencil,用来做笔记、做批注、写写字都绰绰有余了。在这里…

【Vue+Element-plus】记录后台首页多echart图静态页面

一、页面效果 二、完整代码 Index.vue <template><div><div><DateTime /><!-- {{username}} --></div><el-row :gutter"20"><el-col :span"8"><div class"grid-content bg-purple"><P…

Python-OpenCV中的图像处理-图像轮廓

Python-OpenCV中的图像处理-图像轮廓 轮廓什么是轮廓查找轮廓绘制轮廓 轮廓特征图像的矩轮廓面积轮廓周长&#xff08;弧长&#xff09;轮廓近似凸包轮廓边界矩形 轮廓 什么是轮廓 轮廓可以简单认为成将连续的点&#xff08;连着边界&#xff09;连在一起的曲线&#xff0c;具…

分布式 - 服务器Nginx:一小时入门系列之动静分离

文章目录 1. 动静分离的好处2. 分离静态文件3. 修改 Nginx 配置文件 1. 动静分离的好处 Apache Tocmat 严格来说是一款java EE服务器&#xff0c;主要是用来处理 servlet请求。处理css、js、图片这些静态文件的IO性能不够好&#xff0c;因此&#xff0c;将静态文件交给nginx处…

os.listdir()读取文件夹下特定命名的文件并合并保存

import pandas as pd from tqdm import tqdm import os # 合并振动信号的所有数据 path D:/code/data/Learning_set/Bearing1_1 acc_csv_files os.listdir(path)acc_data pd.DataFrame() temp_data pd.DataFrame() # 逐个读取并合并CSV文件 # tqdm的作用是显示进度条&#…

【PNC】AStar及常用规划算法原理与实现

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍AStar规划算法原理与实现。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不迷…

网工内推 | 信息安全负责人,需8年安全经验,CISSP证书

01 上海鹰角网络 招聘岗位&#xff1a;信息安全负责人 职责描述&#xff1a; 1、负责公司总体的信息安全规划、信息安全管理体系、流程、制度的设计和优化&#xff0c;确保在运营、应用、信息和业务等方面的持续安全、稳定&#xff1b; 2、负责对系统&#xff0c;网络&#xf…

内网横向移动—WinLinux内存离线读取Hashcat破解RDPSSH存储提取

内网横向移动—Win&Linux&内存离线读取&Hashcat破解&RDP&SSH存储提取 1. 前言2. Windows系统密码提取2.1. 在线读取2.2. 离线读取2.2.1. 无存储读取2.2.1.1. 读取文件2.2.1.2. 本地解密 2.2.2. 有存储读取 2.3. 解决高版本2.3.1. 修改注册表2.3.2. 重新登陆…

Unity3d C#利用本地网页快速打开萤石云监控视频流(ezopen)实现云台,声音等控制,支持WebGL平台,替代UMP播放(含源码)

前言 之前我介绍了替代Universal?Media?PlayerUMP播放石云监控视频流(ezopen)的功能&#xff0c;效果还是很明显的&#xff0c;笔者的测试是差不多3-5秒就能打开监控画面&#xff0c;不过稍微遗憾的是&#xff0c;之前的功能是iframe打开石云提供的播放网页的形式&#xff0…

SSM——环境搭建、产品操作、订单操作

SSM 环境搭建与产品操作 1. 环境准备 1.1 数据库与表结构 1.1.1 创建用户与授权 数据库我们使用 Oracle Oracle 为每个项目创建单独 user &#xff0c; oracle 数据表存放在表空间下&#xff0c;每个用户有独立表空间 创建用户及密码 语法 [ 创建用户 ] &#xff1a; crea…

js 正则表达式

js 正则表达式 http://tool.oschina.net/regex https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions 11 22

【大厂面试必备】网络收发数据及断开服务器(四次挥手)

接上一篇&#xff1a;【网络知识面试】初识协议栈和套接字及连接阶段的三次握手  前面我们了解到服务器和客户端在创建套接字&#xff0c;建立连接后&#xff0c;就可以进入到下一步&#xff0c;双发可以互相发送和接收数据&#xff0c;本篇博客就来学习一下这个过程。  我们…

C++初阶——拷贝构造和运算符重载(const成员)

目录 1. 拷贝构造函数 1.2 拷贝构造函数特征&#xff1a; 2. 默认拷贝构造函数 2.1 未显式定义&#xff0c;编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝&#xff0c;这种拷贝叫做浅拷贝&#xff0c;或者值拷贝 3. 运算符重载 3.1…

机器人CPP编程基础-01第一个程序Hello World

很多课程先讲C/C或者一些其他编程课&#xff0c;称之为基础课程。然后到本科高年级进行机器人专业课学习&#xff0c;这样时间损失非常大&#xff0c;效率非常低。 C/单片机/嵌入式/ROS等这些编程基础可以合并到一门课中进行实现&#xff0c;这些素材已经迭代三轮以上&#xf…

C# Equals()方法报错:NullReferenceException was unhandled

下面是一个C# Equals()方法的例子&#xff0c;执行时报错了 static void Main(string[] args) {string name "sandeep";string myName null;Console.WriteLine(" operator result is {0}", name myName);Console.WriteLine("Equals method result…

中通快递:短期财务前景良好,长期财务业绩将遭受严重打击

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 华尔街分析师对中通快递的短期财务前景预测 华尔街分析师目前预测中通快递&#xff08;ZTO&#xff09;将在2023财年全年产生一份相当不错的财务业绩。 根据S&P Capital IQ的数据&#xff0c;在过去的6个月里&#xff…

代码随想录算法训练营第24天| 第七章 回溯算法part01 理论基础、leetcode 77

Part I : 回溯算法基础 背景&#xff1a;一直以来都是半懂不懂的&#xff0c;在逻辑上不难&#xff0c;毕竟属于暴力搜索&#xff1b;在代码上就开始缠绕起来了&#xff0c;自己研究的时候对N皇后问题老是理不清。这次终于在Carl这开始前进啦&#xff01;何为回溯算法&#xf…

【C++】STL——set/multiset 和 map/multimap的使用

文章目录 1. 关联式容器2. 树形结构的关联式容器3. set3.1 认识set3.1 set的使用 4. multiset5. map5.1 认识map5.2 pair5.3 map的使用对map中[]的理解 6. multimap 1. 关联式容器 在初阶阶段&#xff0c;我们已经接触过STL中的部分容器 比如&#xff1a;vector、list、deque、…

VoxWeekly|The Sandbox 生态周报|20230807

欢迎来到由 The Sandbox 发布的《VoxWeekly》。我们会在每周发布&#xff0c;对上一周 The Sandbox 生态系统所发生的事情进行总结。 如果你喜欢我们内容&#xff0c;欢迎与朋友和家人分享。请订阅我们的 Medium 、关注我们的 Twitter&#xff0c;并加入 Discord 社区&#xf…