【项目日记(八)】第三层: 页缓存的具体实现(下)

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

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

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

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


在这里插入图片描述

项目日记

  • 1. 前言
  • 2. 什么是内存碎片问题?
  • 3. 地址空间上的内存使用情况
  • 4. 页缓存合并内存的代码实现
  • 5. 总结以及对代码的拓展

1. 前言

请先看完页缓存的具体实现(上)

本章重点:

本篇文章着重讲解页缓存是怎样把从中心缓存中还回来的内存挂在桶上,并且进行前后页的内存合并的,合并内存形成更大的一份内存来减少内存碎片的问题


2. 什么是内存碎片问题?

我们拿整个程序地址空间来举例:

在这里插入图片描述

可以看见虽然整个程序地址空间还有300多byte的空间,但是要申请300byte却申请不出来,对于我们这个项目来说,假设有两个在地址空间中相邻的span,一个是10页,一个是15页,分别挂在第10号桶和第15号桶中,假设没有合并内存此时外部申请一个20页的span是申请不出来的,即使现在空闲的空间有25页,所以这也就体现出了这个项目中合并内存的重要性!


3. 地址空间上的内存使用情况

在地址空间中,一共是4GB大小的空间.
地址从0000 0000到FFFF FFFF.

第0页的起始地址是0
第一页的起始地址是8*1024KB
...以此类推

在这里插入图片描述

当中心缓存还回来一个span后,假设这个span中的大页内存在地址空间中是在第1000页,并且span的大小是50页,那么这个还回来的span就处于空闲状态了,此时我们只需要去检查地址空间中第999页的内存是否空闲,如果空闲就将1000~1050页和999页合并,形成一个51页的大块儿span,并且要不断向前合并直到遇见正在使用的页.同理,需要检查地址空间的1051页是否空闲,如果是空闲的,那么就将它一起合并过去!

在这里插入图片描述


4. 页缓存合并内存的代码实现

在pagecache.h文件中:

void PageCache::ReleaseSpanToPageCache(SpanData* span)
{
	if (span->_n > N_PAGES - 1)//大于128页的内存直接还给堆,不需要走pagecache
	{
		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 prevret = _idSpanMap.find(prevId);
		if (prevret == _idSpanMap.end())//前面没有页号了
			break;
		SpanData* prevspan = ret;
		if (ret == nullptr)
			break;
		if (prevspan->_isUse == true)//前面的页正在使用
			break;
		if (prevspan->_n + span->_n > N_PAGES - 1)//当前页数加上span的页数大于128了,pagecache挂不下了
			break;
		//开始合并span和span的前面页
		span->_pageid = prevspan->_pageid;
		span->_n += prevspan->_n;
		_spanList[prevspan->_n].Erase(prevspan);//将被合并的页从pagecache中拿下来
		//delete prevspan;//将prevspan中的数据清除,诸如页号,页数等
		_spanPool.Delete(prevspan);
	}
	while (1)//不断往后合并,直到遇见不能合并的情况
	{
		PAGE_ID nextId = span->_pageid + span->_n;
		auto nextret = _idSpanMap.find(nextId);
		if (nextret == _idSpanMap.end())//前面没有页号了
			break;
		//SpanData* nextspan = nextret->second;
		auto ret = (SpanData*)_idSpanMap.get(nextId);
		if (ret == nullptr)
			break;
		SpanData* nextspan = ret;
		if (nextspan->_isUse == true)//前面的页正在使用
			break;
		if (nextspan->_n + span->_n > N_PAGES - 1)//当前页数加上span的页数大于128了,pagecache挂不下了
			break;
		//开始合并span和span的前面页
		span->_n += nextspan->_n;
		_spanList[nextspan->_n].Erase(nextspan);//将被合并的页从pagecache中拿下来
		//delete nextspan;//将prevspan中的数据清除,诸如页号,页数等
		_spanPool.Delete(nextspan);
	}
	//合并完后将span挂起来
	_spanList[span->_n].PushFront(span);
	//合并完后,要重新将这个span的首尾两页的id和这个span进行映射,方便别的span来合并我的时候使用
	_idSpanMap[span->_pageid] = span;
	_idSpanMap[span->_pageid + span->_n - 1] = span;
	span->_isUse = false;
}

对于代码的解释都在注释当中,大家可以发现整个合并内存的过程中,我们已经将delete操作符替换为了定长池中的free,这也就是完全脱离了free函数,并且当合并后的页数大于了128,此时整个页缓存哈希桶是挂不下的,所以要特别注意这一种情况


5. 总结以及对代码的拓展

页缓存结构的讲解已经结束,现在回头来看前面设计的这三层缓存结构,可谓是非常之巧妙,第一层线程缓存是无锁的,申请/释放内存非常高效,而第二层中心缓存是用的桶锁,在大多数情况下也没有竞争锁的问题,效率也非常高,所以现在能理解为什么要设计三层而不是两层,甚至是一层,一方面是为了效率的考量,另一方面是为了可以方便合并相邻的空闲页

对代码的拓展:

在使用到了直接向系统返还内存的函数:

inline static void SystemFree(void* ptr)
{
#ifdef _WIN32
	VirtualFree(ptr, 0, MEM_RELEASE);
#else
	// sbrk unmmap等
#endif
}

同样,这份代码知道就行了,不需详谈


🔎 下期预告:项目的测试以及优化🔍

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

国内外b2b网站大全,免费b2b网站平台有哪些?

B2B网站大全平台主要是提供各类B2B网站的免费收录和分类&#xff0c;涵盖了外贸、机械、建筑、化工、五金、电工、农林、仪器、食品、能源、服装、冶金、电子等&#xff0c;这些B2B网站可以帮助中小企业和中国制造业提供在线采购、供求信息&#xff0c;招标信息。 免费B2B网站分…

[Tomcat问题]--使用Tomcat 10.x部署项目时,出现实例化Servlet类[xxx]异常

[Tomcat问题]–使用Tomcat 10.x部署项目时&#xff0c;出现实例化Servlet类[xxx]异常 本片博文在知乎同步更新 环境 OS: Windows 11 23H2Java Version: java 21.0.1 2023-10-17 LTSIDE: IntelliJ IDEA 2023.3.3Maven: Apache Maven 3.9.6Tomcat: Tomcat 10.1.18 ReleasedSer…

2024年【安全员-B证】考试资料及安全员-B证模拟考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年安全员-B证考试资料为正在备考安全员-B证操作证的学员准备的理论考试专题&#xff0c;每个月更新的安全员-B证模拟考试题库祝您顺利通过安全员-B证考试。 1、【多选题】《中华人民共和国安全生产法》规定&#…

C语言:详解操作符(上)

摘要&#xff1a; 本篇&#xff0c;我们将学习C语言中操作符的相关内容&#xff0c;操作符是C语言中重要的元素之一&#xff0c;在我们的代码中处处都有&#xff0c;下面我们将详细介绍操作符的相关内容&#xff0c;并结合一些代码例题加深印象。 目录 一、操作符的分类及介绍 …

黑马头条D1 导学

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 知…

ChatGPT实战100例 - (15) 还不会写 Stable Diffusion (SD) 绘画提示词?没关系,ChatGPT帮你搞定

文章目录 ChatGPT实战100例 - (15) 还不会写 Stable Diffusion (SD) 绘画提示词&#xff1f;没关系&#xff0c;ChatGPT帮你搞定一、把场景描述转为镜头语言二、把镜头语言转换为Prompt三、把Prompt转换为图片 ChatGPT实战100例 - (15) 还不会写 Stable Diffusion (SD) 绘画提示…

指针详解(3)

各位少年&#xff0c;大家好&#xff0c;我是博主那一脸阳光&#xff0c;今天介绍 二级指针 指针数组&#xff0c;还有个指针数组模拟二维数组。 前言&#xff1a;在浩瀚的C语言编程宇宙中&#xff0c;指针犹如一把打开内存世界大门的独特钥匙&#xff0c;它不仅是理解程序运行…

牛客寒假算法基础集训营1 E本题主要考察了贪心

示例1 输入 3 4 3 2 4 5 8 1 2 1 4 2 4 3 1 3 1 1 2 3 6 6 1 2 3 4 5 6 2 3 2 3 3 4 4 5 5 6 6 1 输出 1 1 4 #include<bits/stdc.h> using namespace std; int u0,m,n; int num100,tempnum1;//tempnum表示当前这一组合鸡的排名&#xff0c;num是最终排名 pair<i…

JAVA学习之面向对象

JAVA学习之面向对象 PART ONE&#xff1a;面向对象基础 1.类与对象&#xff1a; 类是一种抽象的概念&#xff0c;它描述了一类具有相似属性和行为的对象的集合。类定义了对象的属性和行为&#xff0c;并且可以作为创建对象的模板。 对象是类的实例&#xff0c;它是类的具体…

[RAM] DRAM 导论:DDR4 | DDR5 | LPDDR5 | GDRR6 | HBM 应运而生

主页&#xff1a;元存储 全文 7700 字&#xff0c;原创请勿转载。 DRAM: where memory meets potential." - Bill Gates 前言 有数据的地方就有存储&#xff0c; 内存是谁都离不开的产品。DRAM主要负责硬盘、主板、显卡等硬件与处理器之间的数据交换。 本博客将介绍D…

STM32--HAL库定时器学习记录(易懂)--持续学习

一、什么是定时器 定时器就是计数器&#xff0c;通过计数完成一系列功能。 二、定时器的分类 定时器分为基本定时器、通用定时器、高级定时器。级别不同&#xff0c;功能不同。级别越高&#xff0c;功能越强。 三、定时器&#xff08;计数器&#xff09;三个重要寄存器 预分…

快速上手AI代码生成:CodeGeeX

1. VSCode等IDE插件直接搜到 CodeGeeX 就可以安装&#xff0c;装上之后&#xff0c;会看到左侧出现了&#xff1a; 2. 登陆以后&#xff0c;在代码区域就可以直接用了。 3. 官网功能说明文档&#xff08;非常简洁清晰&#xff09;&#xff1a; https://zhipu-ai.feishu.cn/wik…

机器学习系列——(九)决策树

简介 决策树作为机器学习的一种经典算法&#xff0c;在数据挖掘、分类和回归等任务中广泛应用。本文将详细介绍机器学习中的决策树算法&#xff0c;包括其原理、构建过程和应用场景。 原理 决策树是一种基于树状结构的监督学习算法&#xff0c;它通过构建一棵树来对数据进行分…

以太网帧格式及ARP协议简介

在以太网中&#xff0c;一个主机和另一个主机进行通信&#xff0c;必须要知道目的主机的MAC地址&#xff08;物理地址&#xff09;&#xff0c;只要知道目的主机的IP地址&#xff0c;就可以通过ARP协议获取目的主机的MAC地址。 1、ARP协议简介 ARP&#xff08;Address Resolut…

2024年【熔化焊接与热切割】考试题及熔化焊接与热切割操作证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 熔化焊接与热切割考试题根据新熔化焊接与热切割考试大纲要求&#xff0c;安全生产模拟考试一点通将熔化焊接与热切割模拟考试试题进行汇编&#xff0c;组成一套熔化焊接与热切割全真模拟考试试题&#xff0c;学员可通…

京东广告算法架构体系建设--高性能计算方案最佳实践 | 京东零售广告技术团队

1、前言 推荐领域算法模型的在线推理是一个对高并发、高实时有较强要求的场景。算法最初是基于Wide & Deep相对简单的网络结构进行建模&#xff0c;容易满足高实时、高并发的推理性能要求。但随着广告模型效果优化进入深水区&#xff0c;基于Transformer用户行为序列和Att…

网络原理TCP/IP(3)

文章目录 滑动窗口流量控制拥塞控制延迟应答捎带应答 滑动窗口 确认应答策略,对每⼀个发送的数据段,都要给⼀个ACK确认应答.收到ACK后再发送下⼀个数据段.这样做有⼀个比较大的缺点,就是性能较差.尤其是数据往返的时间较长的时候. 为了解决低效率传输&#xff0c;引入了滑动窗…

镜舟科技客户成功团队负责人孟庆欢:湖仓一体将成为数据架构的新范式

大数据产业创新服务媒体 ——聚焦数据 改变商业 随着数字化的概念逐步深入不同领域企业的运营中&#xff0c;业务形态和数字化路径也越来越丰富。这也为企业数据处理、储存的方式提出了更多要求。对于企业&#xff0c;尤其是数据驱动型企业来说&#xff0c;需要强大的解决方案…

STM32F407 CAN 静默回环模式 配置

CAN 静默回环模式 【 Silent_LoopBack】 自发自收&#xff0c;这种方式作“热自检”使用&#xff0c;即自我检查&#xff0c;不干扰总线&#xff0c;也不受总线干扰. 发送&#xff1a;发出的数据&#xff0c;只会传输到自己的输入端&#xff0c;不会影响总线.接收&#x…

隐写术:隐藏信息的秘密艺术

一、引言 隐写术&#xff0c;这个充满神秘色彩的词汇&#xff0c;似乎让我们回到了间谍和秘密特工的时代。但实际上&#xff0c;隐写术在现代社会仍然有着广泛的应用&#xff0c;例如在军事、情报、商业等领域。本文将带你走进隐写术的世界&#xff0c;探索它的原理、应用和防…