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

高并发内存池(回收)[4]

threadcache还给centralcache

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.PopRange(start, end, list.MaxSize());CentralCache::GetInstance()->ReleaseListToSpans(start, size);
}

centralcache回收

函数CentralCache::ReleaseListToSpans的实现,用于释放一组内存块到对应的Span中。

函数的输入参数是startsize,分别表示要释放的内存块的起始地址和大小。

函数的主要逻辑如下:

  1. 根据内存块的大小size计算出对应的SizeClass的索引index
  2. 获取对应索引的SpanList,并对其进行加锁。
  3. 进入一个循环,遍历要释放的内存块链表,直到遍历完所有内存块。
  4. 在循环中,首先获取当前内存块的下一个内存块地址next
  5. 根据当前内存块的地址start,通过PageCache::GetInstance()->MapObjectToSpan函数获取对应的Span。
  6. 将当前内存块加入到Span的空闲内存块链表中,并更新Span的使用计数和空闲内存块链表头指针。
  7. 如果Span的使用计数变为0,说明所有切分出去的小块内存都回来了,可以将该Span再次回收给PageCache。
  8. 在释放Span给PageCache之前,先解锁SpanList,然后加锁PageCache的锁,以确保线程安全。
  9. 释放Span给PageCache后,重新加锁SpanList,准备继续处理下一个内存块。
  10. 更新start为下一个内存块的地址,继续循环直到所有内存块都处理完毕。
  11. 最后,解锁SpanList,函数执行完毕。

这段代码的作用是将一组内存块释放到对应的Span中,并在Span的使用计数变为0时将Span回收给PageCache。

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--;// 说明span的切分出去的所有小块内存都回来了// 这个span就可以再回收给page cache,pagecache可以再尝试去做前后页的合并if (span->_useCount == 0){_spanLists[index].Erase(span);span->_freeList = nullptr;span->_next = nullptr;span->_prev = nullptr;// 释放span给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();
}
Span* PageCache::MapObjectToSpan(void* obj)
{PAGE_ID id = ((PAGE_ID)obj >> PAGE_SHIFT);auto ret = _idSpanMap.find(id);if (ret != _idSpanMap.end()){return ret->second;}else{assert(false);return nullptr;}
}

释放span到pagecache

这段代码是一个函数PageCache::ReleaseSpanToPageCache的实现,用于将Span回收给PageCache,并尝试进行前后页的合并,以缓解内存碎片问题。

函数的输入参数是一个指向Span对象的指针span

函数的主要逻辑如下:

  1. 使用一个循环,不断尝试合并Span的前面的页,直到不满足合并条件为止。
  2. 在循环中,首先计算出前一个页的页号prevId,然后在_idSpanMap中查找前一个页的Span。
  3. 如果前一个页的Span不存在,则跳出循环。
  4. 如果前一个页的Span正在使用中,则跳出循环。
  5. 如果合并后的Span的页数超过了NPAGES-1,则跳出循环。
  6. 更新合并后的Span的页号和页数,并从SpanList中移除前一个页的Span。
  7. 删除前一个页的Span。
  8. 继续循环,尝试合并Span的后面的页,直到不满足合并条件为止。
  9. 在循环中,首先计算出后一个页的页号nextId,然后在_idSpanMap中查找后一个页的Span。
  10. 如果后一个页的Span不存在,则跳出循环。
  11. 如果后一个页的Span正在使用中,则跳出循环。
  12. 如果合并后的Span的页数超过了NPAGES-1,则跳出循环。
  13. 更新合并后的Span的页数,并从SpanList中移除后一个页的Span。
  14. 删除后一个页的Span。
  15. 将合并后的Span插入到对应的SpanList的头部。
  16. 设置合并后的Span的使用标志为false。
  17. 更新_idSpanMap,将合并后的Span的页号和页号+页数-1都映射到该Span。
  18. 函数执行完毕。

这段代码的作用是将Span回收给PageCache,并尝试进行前后页的合并,以缓解内存碎片问题。合并的条件包括前后页存在且未使用,并且合并后的Span的页数不超过NPAGES-1。

void PageCache::ReleaseSpanToPageCache(Span* span)
{// 对span前后的页,尝试进行合并,缓解内存碎片问题while (1){PAGE_ID prevId = span->_pageId - 1;auto ret = _idSpanMap.find(prevId);// 前面的页号没有,不合并了if (ret == _idSpanMap.end()){break;}// 前面相邻页的span在使用,不合并了Span* prevSpan = ret->second;if (prevSpan->_isUse == true){break;}// 合并出超过128页的span没办法管理,不合并了if (prevSpan->_n + span->_n > NPAGES - 1){break;}span->_pageId = prevSpan->_pageId;span->_n += prevSpan->_n;_spanLists[prevSpan->_n].Erase(prevSpan);delete prevSpan;}// 向后合并while (1){PAGE_ID nextId = span->_pageId + span->_n;auto ret = _idSpanMap.find(nextId);if (ret == _idSpanMap.end()){break;}Span* nextSpan = ret->second;if (nextSpan->_isUse == true){break;}if (nextSpan->_n + span->_n > NPAGES - 1){break;}span->_n += nextSpan->_n;_spanLists[nextSpan->_n].Erase(nextSpan);delete nextSpan;}_spanLists[span->_n].PushFront(span);span->_isUse = false;_idSpanMap[span->_pageId] = span;_idSpanMap[span->_pageId + span->_n - 1] = span;
}

相关文章:

高并发内存池(回收)[4]

threadcache还给centralcache void ThreadCache::Deallocate(void* ptr, size_t size) {assert(ptr);assert(size < MAX_BYTES);// 找对映射的自由链表桶&#xff0c;对象插入进入size_t index SizeClass::Index(size);_freeLists[index].Push(ptr);// 当链表长度大于一次…...

分布式事务篇-2.4 Spring-Boot整合Seata

文章目录 前言一、pom jar导入:二、项目配置&#xff1a;2.1 配置 说明&#xff1a;2.1 .1 seata server 端:2.1 .2 seata client 端: 2.2 开启seata 对于数据源的代理:2.3 seata-client 的注册中心&#xff1a;2.4 seata-client 的配置中心&#xff1a;2.5 去掉手写的数据源代…...

718. 最长重复子数组

718. 最长重复子数组 原题链接&#xff1a;完成情况&#xff1a;题解&#xff1a;方法一&#xff1a;动态规划方法二&#xff1a;滑动窗口方法三&#xff1a;二分查找 哈希 原题链接&#xff1a; 718. 最长重复子数组 https://leetcode.cn/problems/maximum-length-of-repe…...

Mysql join加多条件与where的区别

最近在项目中遇到一个问题&#xff0c;感觉有点意思&#xff0c;在解决问题及查阅了相关资料后&#xff0c;打算写篇文章给朋友们分享一下。 问题现象&#xff1a; 问题是很常见的空指针问题&#xff0c;后端查询数据库数据&#xff0c;遍历进行相关业务处理时报空指针。通过…...

div滚动条自动滚动到底部

<div id"center"></div>// 滚动条到最底部scrollToBottom(){var box document.getElementById(center);this.$nextTick(() > {box.scrollTop box.scrollHeight})},...

【深度学习】实验02 鸢尾花数据集分析

文章目录 鸢尾花数据集分析决策树K-means 鸢尾花数据集分析 决策树 # 导入机器学习相关库 from sklearn import datasets from sklearn import treeimport matplotlib.pyplot as plt import numpy as np# Iris数据集是常用的分类实验数据集&#xff0c; # 由Fisher, 1936收集…...

AI大模型潮水中,医疗数字化加速「求解」

蝴蝶挥动翅膀&#xff0c;医疗行业每个角落开始连锁反应&#xff0c;曾经被忽视的问题也愈发明显。但与之对应的是&#xff0c;对数字化和AI大模型的价值认可&#xff0c;在中国医疗赛道也正在加速来临。 作者|斗斗 编辑|皮爷 出品|产业家 重庆市某地方人民医院&#xf…...

【安卓】自定义View实现画板涂鸦等功能

一、实现效果 二、代码 1、MainActivity.class package com.lsl.mydrawingboarddemo;import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat;import android.os.Bundle; import android.os.Handler; import android.view.View; impo…...

面试题. 搜索旋转数组

搜索旋转数组。给定一个排序后的数组&#xff0c;包含n个整数&#xff0c;但这个数组已被旋转过很多次了&#xff0c;次数不详。请编写代码找出数组中的某个元素&#xff0c;假设数组元素原先是按升序排列的。若有多个相同元素&#xff0c;返回索引值最小的一个。 示例1: 输入…...

前端需要理解的数据治理与异常监控知识

1 数据治理 前端数据治理的重要指标是准确性和数据&#xff0c;一个数据对象包括数据值和其他元数据。 2 数据上报方式 2.1 Image 通过将采集的数据拼接在图片请求的后面&#xff0c;向服务端请求一个 1*1 px 大小的图片&#xff08;gif&#xff09;实现的&#xff0c;设置…...

ip_vs 原理解析 (四)hook 后的开始 一

文章目录 ip_vs hook 后NF_INET_LOCAL_IN 本章重点&#xff1a; k8s 如何利用 ip_vs 实现源 IP 会话亲和性。 ip_vs hook 后 NF_INET_LOCAL_IN 根据优先级依次是 ip_vs_reply4&#xff0c;ip_vs_remote_request4 ip_vs_reply4| -- ip_vs_out| -- skb_to_full_sk(skb&#xf…...

【论文解读】基于图的自监督学习联合嵌入预测架构

一、简要介绍 本文演示了一种学习高度语义的图像表示的方法&#xff0c;而不依赖于手工制作的数据增强。论文介绍了基于图像的联合嵌入预测架构&#xff08;I-JEPA&#xff09;&#xff0c;这是一种用于从图像中进行自监督学习的非生成性方法。I-JEPA背后的idea很简单&#xff…...

C++ 容器

string 1. 构造 string s1(); // 1 string s2("hello"); // hello string s3(3, k); // kkk string s4("hellohello", 2, 4); // lloh2. 赋值 string s1 "hellohello"; // hellohello string s2.assign(s1); // he…...

【PHP】PHP文件操作详解

PHP是一种广泛使用的服务器端脚本语言&#xff0c;用于开发Web应用程序。在PHP中&#xff0c;文件操作是一项重要的功能&#xff0c;包括文件的读取、写入、删除和其他操作。本文将详细介绍PHP文件操作的各个方面&#xff0c;并通过示例代码进行说明。 一、文件读取 要读取一…...

硬核旗舰南卡OE CC开放式耳机发布,重新定义百元开放式耳机新标杆!

​随着现在健康意识的不断提高&#xff0c;人们对于日常用品的要求越来越高&#xff0c;在耳机市场中&#xff0c;健康因素也逐渐成为消费者所考虑的因素之一&#xff0c;入耳式耳机因为会引发中耳炎、耳膜炎等疾病&#xff0c;正在逐渐被开放式蓝牙耳机所取代&#xff0c;南卡…...

785. 判断二分图

785. 判断二分图 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a; 原题链接&#xff1a; 785. 判断二分图 https://leetcode.cn/problems/is-graph-bipartite/description/ 完成情况&#xff1a; 解题思路&#xff1a; 题目解释&#x…...

限时 180 天,微软为 RHEL 9 和 Ubuntu 22.04 推出 SQL Server 2022 预览评估版

导读近日消息&#xff0c;微软公司今天发布新闻稿&#xff0c;宣布面向 Red Hat Enterprise Linux&#xff08;RHEL&#xff09;9 和 Ubuntu 22.04 两大发行版&#xff0c;以预览模式推出 SQL Server 2022 评估版。 近日消息&#xff0c;微软公司今天发布新闻稿&#xff0c;宣布…...

一款ccm的功率因素校正控制器ncp1654

产品概述&#xff1a; NCP1654是用于连续传导模式的控制器&#xff08;CCM&#xff09;功率因数校正升压预转换器。它控制固定频率模式下的电源开关导通时间&#xff08;PWM&#xff09;并且取决于瞬时线圈电流。 该电路封装在SO8封装中&#xff0c;最大限度地减少了外部组件&a…...

4.若依框架上传文件

1.服务端代码-控制器 /*** 上传文件*/PostMapping("/upload")Operation(summary "上传")public AjaxResult uploadFile(MultipartFile file) throws Exception {try {// 上传文件路径String filePath RuoYiConfig.getUploadPath();// 上传并返回新文件名…...

Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required

项目场景&#xff1a; 最近因为公司业务需要在搭一个新架构&#xff0c;用的springboot3和jdk17,在整合mybatis多数据源的时候报错 &#xff08;引用的mybatisplus 和 mybatisplusjion的是最新的包-2023-08-26&#xff09; Error creating bean with name ‘XXXServiceImpl’:…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

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

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

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...