【项目日记(六)】第二层: 中心缓存的具体实现(下)

news2024/12/22 19:50:00

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

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

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

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


在这里插入图片描述

项目日记

  • 1. 前言
  • 2. 中心缓存回收/还回内存的细节
  • 3. 中心缓存回收内存的代码实现
  • 4. 对于页号与span映射的代码补充
  • 5. 总结

1. 前言

本篇文章在上一篇文章的基础
上,对中心缓存的释放内存做补充

上一篇: 中心缓存具体实现(上)

本章重点:

本篇文章着重讲解中心缓存这一层
释放内存的全部过程,包括如何在线程
缓存中回收小块儿内存,以及如何将
自己的大块span内存还给页缓存


2. 中心缓存回收/还回内存的细节

  • 第一步: 当线程缓存中的哈希桶中小块儿内存的个数大于了该线程缓存一次性向中心缓存中申请的小块儿内存的个数,此时小块儿内存会从线程缓存中还回到中心缓存的span中

在这里插入图片描述

细节问题一:

从线程缓存中还回来的小块儿内存是多个,然而中心缓存的桶中可能不止一个span,我们怎么知道哪个小块儿内存对应到哪个span?很明显随意将在小块儿内存还回到任意span肯定是不对的!在上一篇文章中我们提到过如何通过指针得到这块儿空间在程序地址空间上的页号,所以我们可以使用一个unordered_map来存储页号和span的映射关系,当线程缓存还回小块儿内存时,可以通过计算小块儿内存在地址空间的页号来从这个哈希表中找到对应的span,这就是解决了我们的问题!

在这里插入图片描述

  • 第二步:当中心缓存中的span结构体中的成员变量:use_count等于0时,代表这个span被分配出去的小块儿内存都已经还回来了,所以此时将这个span整体还给上一级,也就是页缓存

3. 中心缓存回收内存的代码实现

根据上面的讲解,每还回来一个小块儿
内存都要检查一下它对应的span结构
的use_count是否为0,如果为0就要将
整个span结构还给页缓存!

centralcache.h文件:

void CentralCache::ReleaseListToSpans(void* start, size_t size)//一个桶中有多个span,这些内存块儿属于哪个span是不确定的
{
	size_t index = AlignmentRule::Index(size);//计算在哪个桶
	_spanlist[index]._mtx.lock();
	//要想知道这些内存块分别在哪个span,将内存块的地址除8*1024,得到这个内存块属于第几页
	while (start != nullptr)
	{
		void* next = *(void**)start;
		SpanData* span = PageCache::GetInstance()->MapObjectToSpan(start);//利用地址与span的映射函数,找到这个内存块对应的span
		*(void**)start = span->_freeList;//将内存块start头插到span中
		span->_freeList = start;
		span->_useCount--;//还回来一次内存块,就将usecount--,减到0后就又把内存还给pagecache
		if (span->_useCount == 0)//此时说明span切分出去的所有小块儿内存都被还回来了,直接将整个span还给pagecache,pagecache再进行前后页的合并
		{
			_spanlist[index].Erase(span);
			span->_freeList = nullptr;//span中的小块内存已经打乱了,但我知道起始地址和结束地址,可直接置空
			span->_next = nullptr;
			span->_prev = nullptr;
			//还回来内存时不用加桶锁了,但是pagecache的整体大锁需要加上
			_spanlist[index]._mtx.unlock();
			PageCache::GetInstance()->_mtx.lock();
			PageCache::GetInstance()->ReleaseSpanToPageCache(span);
			PageCache::GetInstance()->_mtx.unlock();
			_spanlist[index]._mtx.lock();
		}
		start = next;
	}
	_spanlist[index]._mtx.unlock();
}

注:对于代码的解释都在注释中
并且ReleaseSpanToPageCache函数
是页缓存需要实现的,这里暂时放一放


4. 对于页号与span映射的代码补充

由于这份代码是在pagecache中存放的并且页缓存还没有具体解释,所以看不懂没关系,把页缓存部分学完就都明白了.再一个,存储页号和span的映射关系的哈希表是存储在页缓存中的!因为不止在中心缓存中会使用到这种映射关系,在页缓存时同样页面临相同的问题,所以将它放在了最上层的页缓存中

pagecache.h文件中:

std::unordered_map<PAGE_ID, SpanData*> _idSpanMap;//存储页号和桶中对应的span的映射,解决换回来的内存对应哪个span的问题
//给我一个地址,返回这个地址对应的span
SpanData* PageCache::MapObjectToSpan(void* obj)
{
	PAGE_ID pageId = (PAGE_ID)obj >> PAGE_SHIFT;//将地址右移13位就算出了页号
	std::unique_lock<std::mutex> lock(_mtx);//加锁
	auto ret = _idSpanMap.find(pageId);
	if (ret != _idSpanMap.end())//若找到了对应的页号,就返回对应的span
		return _idSpanMap[pageId];
	else assert(false);//没找到,证明前面的代码有问题
	assert(ret != nullptr);
	return ret;
}

5. 总结

中心缓存这一层的所有内容已经讲解完毕,很巧妙的是,中心缓存使用的是桶锁,只有两个不同的线程同时进入到同一个桶中才会有锁竞争问题,这也是这个项目比较快的原因之一.总的来说,中心缓存的作用是承上启下,负责给线程缓存分配切分好的小块儿内存,以及从线程缓存中回收内存.并且它也会向页缓存申请大块儿内存,并且会在合适的时候将大块儿内存还回去,方便页缓存结构进行内存合并!


🔎 下期预告:页缓存的具体实现🔍

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

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

相关文章

fullcalendar案例

fullcalendar案例 <script srchttps://cdn.jsdelivr.net/npm/fullcalendar6.1.10/index.global.min.js></script><script srchttps://code.jquery.com/jquery-3.6.0.min.js></script> <!-- 引入 jQuery CDN --><script>document.addEventL…

防御挂马攻击:从防御到清除的最佳实践

挂马攻击&#xff0c;也称为马式攻击&#xff08;Horse Attack&#xff09;&#xff0c;是一种常见的网络攻击手段。攻击者通过在目标服务器或网站中植入恶意程序&#xff0c;以获取系统权限或窃取敏感信息。为了应对这种威胁&#xff0c;本文将重点介绍防御挂马攻击的最佳实践…

D6282——4.6W 双路音频功率放大电路,开机噪音小内置热保护电路,最佳电源电压 9V、12V, 工作电源电压范围:Vcc=6~15V

D6282 是双路音频功率放大集成电路&#xff0c;内置温度过热保护电路、功率调 整开关。适用于便携式收录机作音频功率放大。 该电路采用 FSIP12 的封装形式封装。 主要特点&#xff1a;  输出功率大 P OUT 2.5W/CH( 典型 ) (Vcc9V,R L 4 Ω ,f1kHz,THD10%) P OUT 4.6W/…

深度学习与神经网络pytorch版 2.3 线性代数

深度学习与神经网络pytorch版 2.3 线性代数 目录 深度学习与神经网络pytorch版 2.3 线性代数 1. 简介 2. 线性代数 2.3.1 标量 ​编辑2.3.2 向量 2.3.3 矩阵 2.3.4 张量及其性质 2.3.5 降维 2.3.6 非降维求和 2.3.7 点积 2.3.8 矩阵-向量积 2.3.9 矩阵-矩阵乘法 …

什么是八木天线,八木天线的作用是什么?

八木天线的得名其实不是由于其有八根天线。 八木天线由一个有源振子&#xff08;一般用折合振子&#xff09;、一个无源反射器和若干个无源引向器平行排列而成的端射式天线&#xff0c;由提出者的名字命名。 上个世纪二十年代&#xff0c;日本东北大学的八木秀次和宇田太郞两人…

JS逆向实战27——pdd的anti_content 分析与逆向

声明 本文章中所有内容仅供学习交流&#xff0c;抓包内容、敏感网址、数据接口均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&#xff0c;请联系我立即删除&#xff01; 本文已在微信公众号发布 …

Activiti工作流引擎

一、工作流介绍&#xff1a; 1.1 概念&#xff1a; 工作流(Workflow)&#xff0c;就是通过计算机对业务流程自动化执行管理。它主要解决的是“使在多个参与者之间按照某种预定义的规则自动进行传递文档、信息或任务的过程&#xff0c;从而实现某个预期的业务目标&#xff0c;或…

如何合理摆放去耦电容

大多数资料都会提到电容摆放要尽可能靠近芯片&#xff0c;这是从小回路电感的角度来看待这个摆放问题&#xff0c;如下图所示&#xff0c;当逻辑芯片发生信号电平的转换时&#xff0c;配电网络中出现瞬态电流增量dI&#xff0c;这个瞬态电流会流过电源和接地电感从而产生一个噪…

【Unity3D日常开发】Unity3D中Text使用超链接并绑定点击事件

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 在开发中遇到了要给Text加超链接的需求&#xff0c;研究了实现…

在充满未知变化的市场社会环境里,实现组织结构与管理方式的自我进化

一、教程描述 本套教程立足于充满变化的市场社会环境&#xff0c;以管理者的素养作为切入点&#xff0c;从组织创新的角度&#xff0c;剖析企业可持续发展的内核与共性&#xff0c;并且提供了一套完整的实践方法论&#xff0c;可以帮助管理者在环境变化中&#xff0c;搭建一个…

npm 淘宝镜像正式到期

由于node安装插件是从国外服务器下载&#xff0c;如果没有“特殊手法”&#xff0c;就可能会遇到下载速度慢、或其它异常问题。 所以如果npm的服务器在中国就好了&#xff0c;于是我们乐于分享的淘宝团队干了这事。你可以用此只读的淘宝服务代替官方版本&#xff0c;且同步频率…

开源微信投票小程序源码系统:PHP+MySQL组合开发 带完整的搭建教程

微信小程序的普及&#xff0c;越来越多的活动和比赛开始采用微信投票的方式来决定胜出者。然而&#xff0c;市面上的微信投票小程序大多数需要付费使用或者功能受限。为了满足广大用户的需求&#xff0c;小编给大家分享一款开源的微信投票小程序源码系统&#xff0c;采用PHPMyS…

android远程投屏应用

客户端app地址&#xff1a;https://gitee.com/youzilzk/blue1.git 服务端地址&#xff1a;https://gitee.com/youzilzk/blue-server1.git 一。服务端部署 1.安装postgres 2.导入项目下blue.sql文件 3.修改配置application.properties和config.properties&#xff0c;其中applic…

【Git】02 仓库、区域与基本操作

文章目录 一、Git仓库二、Git区域三、操作3.1 git add3.2 更改文件名3.3 清空暂存区3.4 帮助文档 四、版本历史4.1 日志时间格式4.2 查看版本演变历史 五、总结 一、Git仓库 Git仓库&#xff0c;可简单理解为项目代码存放的位置&#xff0c;Git将该项目目录中的内容纳入版本管…

【Java基础】之进程与线程

进程与线程 1. 线程与进程1.1 概念1.2 区别与联系 2. 线程的5种状态和切换2.1 简单介绍2.2 状态切换2.2.1 重点情况 3. 线程中常见的方法4. 线程池 1. 线程与进程 1.1 概念 进程&#xff1a;资源分配的基本单元&#xff0c;如QQ音乐 线程&#xff1a;资源调度的基本单元&…

构建基于Flask的跑腿外卖小程序

跑腿外卖小程序作为现代生活中的重要组成部分&#xff0c;其技术实现涉及诸多方面&#xff0c;其中Web开发框架是至关重要的一环。在这篇文章中&#xff0c;我们将使用Python的Flask框架构建一个简单的跑腿外卖小程序的原型&#xff0c;展示其基本功能和实现原理。 首先&…

React中文官网已经搬迁了,原网址内容将不再更新

注意1&#xff1a;React中文官网已经搬迁至-React 官方中文文档&#xff0c;原网址内容将不再更新 注意2&#xff1a;React官网已经将React的定义由“用于构建用户界面的 JavaScript 库”更改为“用于构建 Web 和原生交互界面的库”。

网易砸10亿造《射雕》,能盘活武侠游戏市场吗?

​网易游戏的2024年,注定是特殊的一年。 在乙游《世界之外》出尽风头的同时,网易有史以来投入最大的武侠游戏《射雕》进行了公测前的最后一次测试,新角色PV陆续公布,宣发也在逐步推进。 这款由网易梦幻事业部战魂工作室研发的全新大世界武侠冒险RPG,可谓是来势汹汹,官方…

python 写入csv文件 内容乱码

问题 python 写入csv文件 内容乱码 详细问题 笔者核心代码 import csv # 将数据写入 CSV 文件 csv_file_path "soil_data.csv" header ["经度", "纬度", "土壤类型", "pH值"]with open(csv_file_path, mode"w&q…

银行数据仓库体系实践(10)--汇总指标层和集市模型设计

建立多层次的数据访问服务体系&#xff0c;有力提升数据仓库的价值。基于指标汇总层、集市层、可以提供面向业务人员的即席数据查询、以及面向应用开发者的数据接口、应用访问接口&#xff0c;满足不同类型应用的需要。 1、汇总指标层模型设计原则及步骤 1.1建设目标&#xff…