【项目日记(三)】内存池的整体框架设计

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:项目日记-高并发内存池⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你做项目
  🔝🔝
开发环境: Visual Studio 2022


在这里插入图片描述

项目日记

  • 1. 前言
  • 2. 内存池整体结构一览
  • 3. 线程缓存结构详解
  • 4. 中心缓存结构详解
  • 5. 页缓存结构详解
  • 6. 总结

1. 前言

由于本项目是模拟学习tcmalloc
的优秀的思想以及巧妙的结构,所
以本项目只会把源项目的精华部分
拿出来学习,请大家耐心看完

本章重点:

本篇文章着重讲解本项目的大致
框架结构,以及每一层小结构的内
部的部分细节,这篇文章不会有很多
的代码演示,但至关重要!!!


2. 内存池整体结构一览

首先,我们采用了三层缓存结构来
实现不同的功能,每一层结构都互
相紧密联系:

  • ThreadCache(线程缓存结构)

线程缓存是每一个线程独享的结构,线程申请和释放内存都在这个缓存中进行,只能用于小于256KB的内存分配.整个线程缓存结构是不用加锁的

  • CentralCache(中心缓存结构)

中心缓存是所有线程所共享的,thread cache是按需从central cache中获取的对象。central cache会在合适的时机回收thread cache中的对象,避免一个线程占用了太多的内存,而其他线程的内存吃紧,达到内存分配在多个线程中更均衡的按需调度的目的。central cache是存在竞争的,所以从这里取内存对象是需要加锁,首先这里用的是桶锁,其次只有thread cache的没有内存对象时才会找central cache,所以这里竞争不会很激烈

  • PageCache(页缓存结构)

页缓存是在central cache缓存上面的一层缓存,存储的内存是以页为单位存储及分配的,central cache没有内存对象时,从page cache分配出一定数量的page,并切割成定长大小的小块内存,分配给central cache。当一个span的几个跨度页的对象都回收以后,page cache会回收central cache满足条件的span对象,并且合并相邻的页,组成更大的页,缓解内存碎片的问题

看到这儿你可能一脸懵逼,但是没关系
这里的所有内容都会在后面一一讲解

三层缓存的大致结构:

在这里插入图片描述


3. 线程缓存结构详解

线程缓存结构实际上是一个哈希桶,
数组的下标代表这个桶中存放的小
块内存的字节数是多少,桶中存放
小块儿内存,就是定长池中的自由链表

在这里插入图片描述

申请内存的步骤:

申请内存时,比如申请8字节大小内存
会先去8字节对应的哈希桶中查看有
没有小块儿内存,如果有,则直接返回
给外部,若对应的桶无小块儿内存,再去
中心缓存中拿内存!

释放内存的步骤:

释放内存时,比如释放的内存大小是16
字节,那么这块儿返回来的空间就会挂
在16字节对应的哈希桶中,当满足某种
条件时,线程缓存中的小块儿内存会还
给中心缓存(最开始的内存是中心缓存给的)


4. 中心缓存结构详解

中心缓存结构本质也是一个哈希桶,
并且它的数组下标和线程缓存是相同
的,但是哈希桶中存储的内容不同,中
心缓存中存储的是一个span结构,span
就是一个结构体,它负责管理大块内存

在这里插入图片描述
对span的简单介绍:

我们默认系统的一页内存是8KB,
span管理的大块儿内存实际上是
大页内存,可能是一页,两页内存,
这个大页内存会被切分为小块儿的
内存,8字节对应的哈希桶中会切分
为8字节的小块儿内存,这样可以很
方便的将小块儿内存分配给线程缓存!

span的来源与去向讲解:

中心缓存的span实际上是由页缓存分配
的,并且在一个span满足某种条件时,会
把此span还给页缓存,并且span是一个
双链表结构,一个哈希桶桶中可能有多个
span,下面是span的大致成员变量:

//管理多个连续页的大块内存跨度结构,centralcache的哈希桶中链接的就是这种结构
class SpanData
{
public:size_t _n = 0;//此span中的页数SpanData* _next = nullptr;SpanData* _prev = nullptr;size_t _useCount = 0;//span中切分好的小对象有几个被使用了void* _freeList = nullptr;//切分好的小块内存的自由链表
};

5. 页缓存结构详解

页缓存结构的本质也是一个哈希桶,
但它的数组下标含义与前两层不同,
它的下标代表这个哈希桶中存放的
span一共有多少页内存!

在这里插入图片描述

span的来源与去向讲解:

页缓存中的span和中心缓存中的
span结构体是一样的,但页缓存中的
span是直接从系统中申请的大块儿
空间,并且这个span会直接分配给中
心缓存去切分为小块儿内存后被使用

向页缓存申请span的基本步骤:

当线程缓存的哈希桶中没有小块儿内存了,并且中心缓存对应的哈希桶中页没有span了,这时会来页缓存申请span回去做切分使用,假设申请的span是5页大小,那么就会去页缓存的五号桶中查看是否有span,若有span就直接返回若没有span,则需要去6到128号桶中寻找是否存在span,假设100号桶中有span,那么会将这个100页的大span切分为一个5页的小span和一个95页的大span,再将这个5页的span返回给中心缓存,这个95页的span重新挂到页缓存的95号桶中!假如6到128号桶都没有span,则会向系统申请一个128页的大块儿空间,再来切分成小span返回!


6. 总结

这整个三层结构的设计是十分巧妙的,
在线程缓存中是不需要加锁的,因为每
个线程独享这个结构,这也是这个项目
比较快的原因之一,在中心缓存中也不
需要完全加锁,而是使用桶锁,只有当不同
的线程进入到同一个桶时才会有锁互斥!

当然这个项目的巧妙之处远不止如此
我将在后面的代码实现中,一边讲解
原理,一边带大家编码,这才能真正带大家
了解到这个项目的精髓与值得学习之处!!!

🔎 下期预告:自由链表和span结构实现🔍

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

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

相关文章

MES管理系统为何成为汽配企业的刚需

随着经济全球化、产品定制化及安全法规的严格化,汽配企业的经营环境变得越来越复杂。中国劳动力资源和原辅料成本的持续上升,导致行业利润率不断下滑。为了应对这些挑战,汽配企业需要引入一种精益制造和管理的工具,而MES管理系统正…

高防CDN与dns结合有哪些优势

高防CDN与DNS结合有哪些优势 随着互联网技术的发展和应用的普及,网络安全问题也日益突出。为了保护网站免受恶意攻击和黑客的侵害,高防CDN与DNS结合被广泛应用于网络安全领域,具有许多优势。 首先,高防CDN与DNS结合可以有效减轻…

PG DBA培训26:PostgreSQL运维诊断与监控分析

本课程由风哥发布的基于PostgreSQL数据库的系列课程,本课程属于PostgreSQL Diagnosis and monitoring analysis,学完本课程可以掌握PostgreSQL日常运维检查-风哥PGSQL工具箱,风哥专用PGSQL工具箱介绍,风哥专用PGSQL工具箱使用&…

四款通用组织架构图模板-一键高清导出

组织架构图作为一种直观的图形化工具,能够帮助我们更好地理解和规划组织结构,提高工作效率。今天,我们就为大家带来四款通用组织架构图模板,让你一键高清导出,轻松搞定组织架构设计! 第一款:某基…

vue实现验证码倒计时功能

开发验证码倒计时功能的必要性 主要是为了防止用户频繁的点击,获取短信验证码是有时间限制的,这样就可以让用户在规定的时间内只能点击一次,在客户端就只是告知用户这个什么时候可以点击,在服务端就可以更少的调用这个接口&#x…

LeetCode-410.分割数组的最大值

原题链接:https://leetcode.cn/problems/split-array-largest-sum/description 题面 给定一个非负整数数组 nums 和一个整数 k ,你需要将这个数组分成 k 个非空的连续子数组。设计一个算法使得这 k 个子数组各自和的最大值最小。 思路 数组定义&#xff…

Excel乱码?教你3个简单解决方法!

“我在编辑一个文件时,Excel突然就乱码了,怎么会这样呢?这个文件对我来说是比较重要的!有什么方法可以快速解决吗?” 在处理Excel文件时,我们有时会遇到乱码问题。乱码不仅影响数据的可读性,还可…

PySide6/PyQt6中Qt窗口标志/窗口属性汇总,如何正确的设置窗口标志/窗口属性

文章目录 📖 介绍 📖🏡 环境 🏡📒 使用方法 📒📚 窗口标志汇总📚 窗口属性汇总📝 使用方法📝 注意事项⚓️ 相关链接 ⚓️📖 介绍 📖 在Qt框架中,窗口标志(window flags)是用于控制窗口的各种属性和行为的强大工具。它们通过设置窗口的属性,如边框…

vue3中Fragment特性的一个bug,需要留意的注意事项

vue3中的Fragment 模版碎片特性是什么&#xff0c;简单的理解就是template模板代码不在像vue2中那样必须在根节点在包裹一层节点了。 vue2写法 <template><div><h1>标题</h1><p>正文内容</p></div> </template>vue3写法 &l…

【OCR项目】之用HALCON的深度学习工具进行文字识别,并导出到C++调用

前言 HALCON是一个强大的机器视觉工具&#xff0c;包含了2D&#xff0c;3D图像各种算子&#xff0c;以及各种任务的深度学习工具&#xff0c;包括目标检测&#xff0c;实例分割&#xff0c;文字识别等。 这次从实际生产的角度&#xff0c;来分享一下如何用HALCON进行文字识别…

Redis(01)——常用指令

基础指令 select 数字&#xff1a;切换到其他数据库flushdb&#xff1a;清空当前数据库flushall&#xff1a;清空所有数据库dbsize&#xff1a;查看数据库大小exists key1[key2 …]&#xff1a;判断当前的key是否存在keys *&#xff1a;查看所有的keyexpire key 时间&#xff…

STM32-串口解析框架

STM32 UART 是最基础的通信接口。本文介绍一种基于 STM32 UART 的通信协议解析框架。与其说是一种解析框架&#xff0c;不如说是一种解析架构&#xff0c;一种解析逻辑更为准确。 测试环境&#xff1a; Master MCU: STM32F103RCT6Slave Module&#xff1a;尚鑫航 SXH485 H200…

运维之道—生产环境安装Redis

目录 1.前言 2.环境准备 2.1 安装gcc依赖 3.部署安装 3.1 下载redis安装包 3.2 解压并编译安装redis 3.3 配置redis ​编辑3.4 启动redis并测试 4. 总结 1.前言 大家好,运维之道的系列文章继续进行,我们今天整理的是Redis生产环境的安装,Redis的安装以及生产环境的…

【数据结构与算法】1.数据结构绪论

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有限&#xff0c;欢迎各位大佬指点&…

10-数组-区域和检索-数组不可变

这是数组的第10篇算法&#xff0c;力扣链接。 给定一个整数数组 nums&#xff0c;处理以下类型的多个查询: 计算索引 left 和 right &#xff08;包含 left 和 right&#xff09;之间的 nums 元素的 和 &#xff0c;其中 left < right 实现 NumArray 类&#xff1a; NumArr…

EOCR电机保护器带煤电厂的具体应用

EOCR系列电动机智能保护器在煤电厂中有广泛的应用。这些保护器具有齐全的保护功能、直观的测量参数、快速的反应灵敏度、可靠的行动以及与上位机通讯构成远程监控的能力&#xff0c;使其成为理想的低压电动机保护及远程监控产品。 在煤电厂中&#xff0c;电动机保护器需要具备过…

【Linux多线程】生产者消费者模型

目录 生产者消费者模型 1. 生产者消费者模式的概念 2. 生产者消费者模型优点 ​编辑3. 生产者消费者模型的特点 基于BlockingQueue&#xff08;阻塞队列&#xff09;的生产者消费者模型 1.BlockingQueue 2. 使用CSTL中的queue来模拟实现阻塞队列 3. 基于任务的生产者消费…

三天吃透Java集合面试八股文

内容摘自我的学习网站&#xff1a;topjavaer.cn 常见的集合有哪些&#xff1f; Java集合类主要由两个接口Collection和Map派生出来的&#xff0c;Collection有三个子接口&#xff1a;List、Set、Queue。 Java集合框架图如下&#xff1a; List代表了有序可重复集合&#xff0c…

Modbus网关BL101 既实现Modbus转MQTT,还能当串口服务器使用

随着工业4.0的迅猛发展&#xff0c;人们深刻认识到在工业生产和生活中&#xff0c;实时、可靠、安全的数据传输至关重要。在此背景下&#xff0c;高性能的工业电力数据传输解决方案——协议转换网关应运而生&#xff0c;广泛应用于工业自动化系统、远程监控和物联网应用应用环境…