高并发内存池(12)-ThreadCache回收内存

高并发内存池(12)-ThreadCache回收内存

代码如下:

// 释放对象时,链表过长时,回收内存回到中心缓存
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);
}
//还给Central的自由链表
void* PopRange(void*&start,void*&end,size_t n)
{assert(n <= _size);start = _freeList;end = start;for (size_t i = 0; i < n - 1; ++i){end = NextObj(end);}_freeList = NextObj(end);NextObj(end) = nullptr;_size -= n;
}

PopRange函数中使用引用参数(void*& start, void*& end)是极其重要的设计选择,有以下几个关键原因:

1. 需要修改调用方的变量

void* start_ptr = nullptr;
void* end_ptr = nullptr;
freeList.PopRange(start_ptr, end_ptr, 5);  // 需要修改start_ptr和end_ptr的值

如果没有引用

  • 函数内部修改的只是参数的副本
  • 调用方的变量不会被实际修改
  • 无法返回提取的内存块链表信息

2. 需要返回两个值

函数需要同时返回:

  • 批量链表的头指针start
  • 批量链表的尾指针end

C++函数只能直接返回一个值,所以必须通过参数返回另一个值。

替代方案对比:

方案1:使用引用参数(当前实现) ✅

void PopRange(void*& start, void*& end, size_t n);
// 清晰,高效,常用

方案2:返回结构体 ❌

struct RangeResult {void* start;void* end;
};
RangeResult PopRange(size_t n);
// 需要定义额外结构体,不够直观

方案3:使用指针参数 ❌

void PopRange(void** start, void** end, size_t n);
// 语法复杂,容易出错

3. 性能零开销

引用在底层通常通过指针实现,但:

  • 语法更简洁:像操作普通变量一样
  • 类型安全:编译器会检查类型匹配
  • 无性能损失:与指针方案性能相同

4. 代码可读性

对比两种写法:

使用引用(清晰)

void* start, *end;
freeList.PopRange(start, end, 5);
// 现在start和end包含了提取的链表

使用指针参数(复杂)

void* start, *end;
freeList.PopRange(&start, &end, 5);
// 需要取地址,容易忘记&

5. 在内存池中的具体应用

// CentralCache向ThreadCache提供内存
void CentralCache::FetchRangeObj(void*& start, void*& end, size_t n)
{// 需要修改start和end来返回内存块链表_freeList.PopRange(start, end, n);// 现在start和end包含了提取的内存块
}

如果不使用引用会怎样?

// 错误版本:不使用引用
void PopRange(void* start, void* end, size_t n)
{start = _freeList;  // 这只是修改局部副本!// 调用方的变量不会被修改
}// 调用代码
void* my_start, *my_end;
freeList.PopRange(my_start, my_end, 5);  // my_start和my_end仍然是nullptr!

总结

使用引用参数void*& start, void*& end是因为:

  1. 需要修改调用方的变量
  2. 需要返回两个值(链表头和尾)
  3. 语法简洁且类型安全
  4. 性能零开销
  5. 代码可读性好

这是C++中常用的"输出参数"模式,特别适合需要返回多个值的场景。在内存池这种高性能组件中,这种设计确保了接口的效率和简洁性。

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

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

相关文章

读大语言模型09超级智能

1. 超级智能1.1. 如果人工智能超越人类智能&#xff0c;可能会成为人类存在的一个重大威胁1.1.1. 对超级人工智能潜在危险最为担忧的群体中&#xff0c;恰恰包括那些否认大语言模型具备真正智能的人1.2. 计算机科学已经成为所有科学领域中不可或缺的重要组成部1.3. GPT具备编写…

阿里云拉取dockers镜像

假如你已经在云服务器上安装了docker需要配置下docker镜像加速代理就行了找到自己的加速网址&#xff1a;然后在云服务器上&#xff0c;修改docker 配置文件&#xff0c;vi /etc/docker/daemon.json没有这个文件的话&#xff0c;需要创建一个。{"default-address-pools&qu…

python自学笔记14 NumPy 线性代数

在Numpy库中有专门的linalg 模块用来做线性代数相关的运算。 本文中线性代数的一般概念不会解释 拆解矩阵 鸢尾花数据矩阵结构如下&#xff08;150 4&#xff09;&#xff1a;取其中的行向量和列向量&#xff1a; # 导入包 import numpy as np from sklearn.datasets import l…

ubuntu20搭建MQTT

sudo apt update sudo apt install mosquitto mosquitto-clients sudo mosquitto_passwd -c /etc/mosquitto/passwd myuser sudo nano /etc/mosquitto/mosquitto.conf# 允许匿名用户连接&#xff08;默认为 true&#xff0c;我们先关闭它&#xff09; allow_anonymous false# 指…

云服务器的主要用途都有哪些?

企业可以利用云服务器构建官方网站&#xff0c;企业官网需要稳定的运行环境来展示产品、服务、公司动态等信息&#xff0c;云服务器提供的高可用性和可扩展性&#xff0c;能保障大量用户同时访问时网站的稳定运行。移动应用的后端服务可以部署在云服务器上&#xff0c;如社交类…

IntelliJ IDEA Debug 模式功能指南

文章目录前言&#x1f4a1; 1. 断点类型与设置&#x1f680; 2. 启动 Debug 模式⚙️ 3. 调试控制按钮详解&#x1f440; 4. 查看与监控变量&#x1f9f0; 5. 高级调试技巧&#x1f48e; 总结前言 作为一名 Java 开发者&#xff0c;熟练掌握调试技巧是提高开发效率的关键。Int…

在pycharmIDE中如何快速掌握一个新模块的使用方法

一、文档使用悬停文档&#xff1a;鼠标悬停在模块/函数上显示文档摘要 (⭐最常用)快速文档&#xff1a;选中标识符按 CtrlQ (Windows/Linux) 或 F1 (Mac)跳转定义&#xff1a;Ctrl左键单击 直接跳转到源码定义处 (⭐最权威)参数提示&#xff1a;输入函数名时自动显示参数列表&a…

win11自定义停止更新方法

一、打开运行窗口&#xff08;winr&#xff09;输入regedit打开注册表编辑器。按照如下路径寻找。计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings二、在Settings页面下右击——>新建——>DWORD(32位)值(D)&#xff0c;并重命名为粉色框中的名字…

Unity委托、匿名方法与事件深度解析:从理论到实战

Unity委托、匿名方法与事件深度解析&#xff1a;从理论到实战 摘要&#xff1a;本文深入剖析Unity中委托、匿名方法与事件的核心机制&#xff0c;结合理论框架与实战案例&#xff0c;帮助开发者掌握高效的事件驱动编程技巧。全文包含12个代码片段及6个核心原理图示框架&#x…

大脑的藏宝图——神经科学如何为自然语言处理(NLP)的深度语义理解绘制新航线

摘要&#xff1a; 截至2025年&#xff0c;大型语言模型&#xff08;LLM&#xff09;已展现出惊人的能力&#xff0c;但其内在的“黑箱”特性和对深层语义理解的局限性也日益凸显。本报告旨在深入探讨一个充满潜力的前沿交叉领域&#xff1a;借鉴地球上最古老、最精密的语言处理…

记录使用ruoyi-flowable开发部署中出现的问题以及解决方法(二)

1.vform的使用与传值 使用动态表单&#xff0c;把当前的用户名传值进动态表单&#xff0c;另外动态表单的上传组件成功后传值会父组件。 在父组件的加载函数中增加&#xff1a; mounted(){this.$refs.vFormRef.addEC("getuploadfile",this);},该方法为给表单加载外…

Apifox 8 月更新|新增测试用例、支持自定义请求示例代码、提升导入/导出 OpenAPI/Swagger 数据的兼容性

Apifox 作为全能 API 工具&#xff0c;正以迅猛之势革新开发者的工作方式&#xff01;想象一下&#xff0c;您正为测试用例编写头疼&#xff0c;或因 OpenAPI 文件导入失败而延误项目&#xff0c;而 Apifox 8 月更新却带来“救命稻草”&#xff1a;新增测试用例功能、自定义请求…

多机多卡微调流程

多机多卡&#xff08;Distributed Training&#xff09;微调大模型是一项复杂但非常高效的任务。它允许你利用多台机器的计算资源来训练一个模型&#xff0c;从而显著缩短训练时间。 多机多卡微调核心流程 整个流程可以概括为以下几个核心步骤&#xff1a; 环境准备与硬件配置 …

Redis(23) RDB和AOF有什么区别?

Redis 的 RDB&#xff08;Redis Database&#xff09;和 AOF&#xff08;Append-Only File&#xff09;是两种主要的持久化机制。每种机制都有其独特的工作方式、优缺点和适用场景。以下是两者的详细比较&#xff0c;并结合代码示例进行解释。 RDB&#xff08;Redis Database&a…

在WSL2 Ubuntu中部署FastDFS服务的完整指南

在WSL2 Ubuntu中部署FastDFS服务的完整指南&#x1f4d6; 前言&#x1f6e0;️ 环境准备1. 系统要求2. Ubuntu应用&#x1f680; 安装服务1. 更新系统2. 安装编译依赖3. 下载源码4. 编译安装&#x1f527; 配置服务1. 设置配置文件2. 创建数据目录3. 配置Tracker服务4. 配置Sto…

新手向:网络编程完全指南

1. 引言&#xff1a;什么是网络编程&#xff1f;网络编程&#xff08;Network Programming&#xff09;是指利用计算机网络实现程序间通信的技术。它构建在计算机网络协议基础上&#xff0c;通过编程实现不同设备间的数据交换与资源共享。从底层协议实现到高层应用开发&#xf…

阿里云——云存储与数据库服务

云存储与数据库服务 数据是数字时代的新石油&#xff0c;而存储与数据库服务就是保存和提炼这些石油的“油库与炼油厂”。阿里云提供了从对象、块、文件存储到关系型、NoSQL、数据仓库的全方位数据服务。本章将帮你构建一套清晰的数据存储选型框架&#xff0c;并掌握核心服务的…

浏览器网页路径扫描器(脚本)

使用网页路径扫描器可以扫描网页的路径&#xff0c;一些工具如ffuf为在命令行上操作&#xff0c;比较不便&#xff0c;而其他资源不好找到 Website path scanner(Script-tampermonkey) 脚本发布在GitHub&#xff0c;本文章也关联文件资源 GitHub:Website path scanner(Script-…

实战原型模式案例

作者&#xff1a;小凯 分享、让自己和他人都能有所收获&#xff01;&#x1f604; 一、前言 老板你加钱我的代码能飞 程序员这份工作里有两种人&#xff1b;一类是热爱喜欢的、一类是仅当成工作的。而喜欢代码编程的这部分人会极其主动学习去丰富自己的羽翼&#xff0c;也非常喜…

微信小程序餐饮扫码点餐小程序堂食外卖桌台自助下单源码

功能说明&#xff1a;商家助手APP、接单更方便前端页面模版随意挑选&#xff0c;可diy精装设计线下买单餐桌点餐快速下单会员管理订单管理优惠券核销叫号取餐排队叫号商品管理桌位管理数据统计售后订单配送设置推广码硬件设备一、技术架构&#xff1a;PHPUniApp构建高性价比系统…