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

【C++项目】高并发内存池第五讲内存回收释放过程介绍

0

内存回收

  • 1.ThreadCache
  • 2.CentralCache
  • 3.PageCache

项目源代码:高并发内存池

1.ThreadCache

void ThreadCache::Deallocate(void* ptr, size_t size)
{assert(ptr);assert(size <= MAX_BYTES);//计算在哪号桶中,然后插入进去size_t index = SizeClass::Index(size);_freeLists[index].Push(ptr);//当链表长度大于一次批量申请的内存时就开始还一段list给central cacheif (_freeLists[index].Size() >= _freeLists[index].MaxSize()){ListTooLong(_freeLists[index], size);}
}void ThreadCache::ListTooLong(FreeList& list, size_t size)
{void* start = nullptr;void* end = nullptr;list.PopRang(start, end, list.MaxSize());CentralCache::GetInstance()->ReleaseListToSpans(start, size);
}

当闲置的内存超过一个批量单位大小的时候就开始回收,首先要计算出要回收到哪个桶的的内存,然后逐级往上回收。

2.CentralCache

void CentralCache::ReleaseListToSpans(void* start, size_t size)
{size_t index = SizeClass::Index(size);_spanLists[index]._mtx.lock();while (start){void* next = Nextobj(start);Span* span = PageCache::GetInstance()->MapObjectToSpan(start);Nextobj(start) = span->_freeList;span->_freeList = start;span->_usecount--;if (span->_usecount == 0)//说明span切分出去的内存小块都回收回来了,//这时这个span就可以再回收给page cache,page cache可以再尝试去做前后页的合并{_spanLists[index].Erase(span);span->_freeList = nullptr;span->_prev = nullptr;span->_next = nullptr;//释放span给page cache时,使用page cache的锁就可以了//所以需要先把桶锁解掉再加page cache的大锁_spanLists[index]._mtx.unlock();PageCache::GetInstance()->_pageMtx.lock();PageCache::GetInstance()->ReleaseSpanToPageCache(span);PageCache::GetInstance()->_pageMtx.unlock();_spanLists[index]._mtx.lock();}start = next;}_spanLists[index]._mtx.unlock();}

CentralCache回收回来还需要做前后页的合并,合成一个大的内存块,然后继续交给PageCache处理

3.PageCache


void PageCache::ReleaseSpanToPageCache(Span* span)
{//大于128页的span,直接还给堆if (span->_n > NPAGES -1){void* ptr = (void*)(span->_pageId << PAGE_SHIFT);SystemFree(ptr);//delete span;_spanPool.Delete(span);return;}//对span前后的页,尝试进行合并,缓解内存碎片问题(外碎片)//对前后的页进行合并while (1){PAGE_ID prevId = span->_pageId - 1;//auto ret = _idSpanMap.find(prevId);前面的页号没有找到,不进行合并//if (ret == _idSpanMap.end())//{//	break;//}auto ret = (Span*)_idSpanMap.get(prevId);if (ret == nullptr){break;}//前面相邻页的span在使用,不进行合并Span* prevSpan = ret;if (prevSpan->_isUse == true){break;}//合并出超过128的span没办法管理,就不能继续合并if (prevSpan->_n + span->_n > NPAGES - 1){break;}//合并span->_pageId = prevSpan->_pageId;span->_n += prevSpan->_n;_spanList[prevSpan->_n].Erase(prevSpan);//delete prevSpan;_spanPool.Delete(prevSpan);}//向后合并while (1){PAGE_ID nextId = span->_pageId + span->_n;/*auto ret = _idSpanMap.find(nextId);if (ret == _idSpanMap.end()){break;}*/auto ret = (Span*)_idSpanMap.get(nextId);if (ret == nullptr){break;}Span* nextSpan = ret;if (nextSpan->_isUse == true){break;}if (span->_n + nextSpan->_n > NPAGES - 1){break;}span->_n += nextSpan->_n;_spanList[nextSpan->_n].Erase(nextSpan);//delete nextSpan;_spanPool.Delete(nextSpan);}_spanList[span->_n].PushFront(span);span->_isUse = false;//_idSpanMap[span->_pageId] = span;_idSpanMap.set(span->_pageId, span);//_idSpanMap[span->_pageId + span->_n - 1] = span;_idSpanMap.set(span->_pageId + span->_n - 1, span);
}

PageCache需要将一页一一页的小块内存何合并成一张大页的内存,来解决内存碎片问题,因为大的可以切成小的,而当申请的内存大于小块的内存碎片时,就会向堆中申请,造成内存浪费。

点赞支持~

请添加图片描述

相关文章:

【C++项目】高并发内存池第五讲内存回收释放过程介绍

内存回收 1.ThreadCache2.CentralCache3.PageCache 项目源代码&#xff1a;高并发内存池 1.ThreadCache void ThreadCache::Deallocate(void* ptr, size_t size) {assert(ptr);assert(size < MAX_BYTES);//计算在哪号桶中&#xff0c;然后插入进去size_t index SizeClass…...

[毕设记录]@学术工具体验:Sread.ai

我是在查RAG相关的时候&#xff0c;在知乎上面看到了这篇回答&#xff1a;浅谈生成式 AI 技术&#xff1a;检索增强生成 RAG - MarvinZ的文章 - 知乎 https://zhuanlan.zhihu.com/p/659248219 然后在末尾看到了这个 sread.ai 在作者主页看到了他关于这个产品的介绍&#xff1a…...

uboot - 驱动开发 - 驱动模型

说明 类似于linux&#xff0c;为了规范、统一驱动适配和驱动接口调用&#xff0c;uboot定义了一套驱动模型(Driver Model)&#xff0c;简称DM。本文基于&#xff1a;u-boot-2021.10。 优点 为同一类ip的驱动定义了统一的操作接口&#xff0c;DM在软件层面做了一定的抽象。分…...

windows 操作系统命令积累

1. 按 "prt sc" 键 截屏 2. 按 "fn" 键让浏览器进入全屏模式&#xff0c;再次按 "fn" 键让浏览器退出全屏模式( ps&#xff1a;惠普笔记本上是 "fn" "f11" ) 3. ipconfig 查看ip信息 4. 查看指定端口被什么进程占用...

数据结构单链表的实现(C语言)

目录 1.实现的接口和功能2.代码块 1.实现的接口和功能 //打印链表 void SLTPrint(SLTNode** phead); //头插 void PushFont(SLTNode** phead, SLTDataType x); //尾插 void PushBack(SLTNode** phead, SLTDataType x); //头删 void PopFont(SLTNode** phead); //尾删 void Pop…...

Postman的高级使用,傻瓜式学习【下】

目录 前言 1、全局变量、环境变量 1.1、概念&#xff1a; 1.2、如何设置全局变量、环境变量 1.3、获取全局变量、环境变量 1.4、案例1&#xff1a;手动设置变量&#xff0c;请求参数获取 1.5、案例2&#xff1a;代码设置变量&#xff0c;代码获取变量 2、Postman读取外部…...

Qt:关闭对话框,动画实现窗体逐渐缩小到消失

关键技术&#xff1a; 1、使用QPropertyAnimation对象&#xff0c;实现动画效果&#xff0c;逐渐缩小窗体尺寸&#xff0c;以及透明度&#xff1b; 2、在对话框缩小时&#xff0c;要将界面中的控件都隐藏起来&#xff0c;并且将对话框布局的Margin修改成0 代码如下&#xff…...

在Windows上 ciphey安装(详细版)

文章目录 前言 一、不想卸载原有的python版本&#xff1f; 二、安装步骤 1.安装python 2.创建虚拟环境vnev 3.在ciphey的虚拟环境中进行激活 4.安装ciphey 三、参数列表 总结 前言 提示&#xff1a;安装了好几次&#xff0c;但是都没安装成功&#xff0c;我使用了三个电脑p…...

【lesson2】数据库的库操作

文章目录 库操作创建数据库删除数据库字符集和校验规则手动设置字符集和校验集不同字符集和校验集之间的区别修改数据库字符集和校验集备份和恢复数据库 库操作 创建数据库 删除数据库 字符集和校验规则 创建数据库的时候&#xff0c;有两个编码集&#xff1a; 1.数据库编码集…...

Android Studio Giraffe解决gradle reload failed问题

settings.gradle.kts中 pluginManagement {repositories {google()mavenCentral()gradlePluginPortal()} } dependencyResolutionManagement {repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)repositories {google()mavenCentral()} } 各增加三行内容&#x…...

刷题笔记day06-哈希表

242.有效的字母异位词 // 思路2&#xff1a;排序后在比较是否相等import ("sort""fmt""io""strings""os" )func isAnagram(s string, t string) bool {s1, s2 : []byte(s), []byte(t)// 从小到大排序sort.Slice(s1, func(i…...

springboot项目中如何实现过滤器鉴权

通常来说鉴权都是写在网关当中&#xff0c;对于单体应用也可以在后台服务中通过一个过滤器实现。其实过程与网关当中的没什么不同&#xff0c;只是在gateway当中目前是基于netty响应式的。过程如下&#xff1a; 一、实现Filter接口 定义自己的过滤器&#xff0c;并且实现Filt…...

【rust/esp32】在idf中使用embedded-graphics控制st7789 LCD屏幕

文章目录 说在前面模块详情准备工作开始编译烧录结果 说在前面 esp32版本&#xff1a;s3运行环境&#xff1a;esp-idf(std)开发环境&#xff1a;wsl2LCD模块&#xff1a;ST7789V2 240*280 LCDgithub地址&#xff1a;这里 模块详情 某宙的esp32s3开发板 某雪的1.69inch LCD模块…...

YOLOv8如何添加注意力模块?

分为两种&#xff1a;有参注意力和无参注意力。 eg: 有参&#xff1a; import torch from torch import nnclass EMA(nn.Module):def __init__(self, channels, factor8):super(EMA, self).__init__()self.groups factorassert channels // self.groups > 0self.softmax …...

用LibreOffice在excel中画折线图

数据表格如下。假设想以x列为横坐标&#xff0c;y1和y2列分别为纵坐标画折线图。 选择插入-》图表&#xff1a; 选择折线图-》点和线&#xff0c;然后点击“下一步”&#xff1a; 选择&#xff1a;列中包含数据序列&#xff0c;然后点击完成&#xff08;因为图挡住了数据…...

RabbitMQ 链接管理-发布者-消费者

RabbitMQ连接管理器 using RabbitMQ.Client; using System; public class RabbitMQConnectionManager { private readonly IConnectionFactory _connectionFactory; private IConnection _connection; public RabbitMQConnectionManager(string hostName) { …...

JAVA中的垃圾回收器(3)----ZGC

一)ZGC介绍:是JAVA11新引入的低延迟垃圾收集器 ZGC是一款基于Regin的&#xff0c;暂时没有分代概念的&#xff0c;使用了读屏障&#xff0c;颜色指针等技术来实现并发的标记清除和标记整理算法&#xff0c;一低延迟为主要目标的一款垃圾回收器 ZGC的regin可以分为是下图中具有大…...

IDEA 如何运行 SpringBoot 项目

步骤一&#xff1a;配置 Maven 第一步&#xff1a;用 IDEA 打开项目&#xff0c;准备配置 maven 环境 &#xff0c;当然如果本地没有提前配置好 maven&#xff0c;就用 IDEA 默认的配置即可 配置 maven 步骤 情况 1&#xff1a;如果本地没有配置过 maven&#xff0c;可以保持如…...

Linux MeterSphere测试平台远程访问你不会?来试试这篇文章

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《粉丝福利》 《C语言进阶篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网…...

15.k8s集群防火墙配置

防火墙配置 ######################## # master节点防火墙设置 ######################### 所有master节点开放相关防火墙端口 $ firewall-cmd --zonepublic --add-port6443/tcp --permanent $ firewall-cmd --zonepublic --add-port2379-2380/tcp --permanent $ firewall-cmd…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

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

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

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官

。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量&#xff1a;setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...