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

高并发内存池(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.xdnf.cn/news/1376713.html

相关文章:

  • 【HTML】隐藏滚动条但保留功能
  • 什么是AI+?什么是人工智能+?
  • redis---set详解
  • ICCV 2025 | 清华IEDA提出GUAVA,单图创建可驱动的上半身3D化身!实时、高效,还能捕捉细腻的面部表情和手势。
  • 《MongoDB 常用命令详解:从数据库操作到高级查询》
  • Windows/Linux 环境下 Jmeter 性能测试的安装与使用
  • 未成功:使用 Nginx 搭建代理服务器(正向代理 HTTPS 网站)
  • Linux学习-TCP并发服务器构建
  • 在 Windows 上部署 Go 语言开发环境
  • 数据分析编程第五步:数据准备与整理
  • JoyAgent-JDGenie开源多智能体系统详解:架构、部署与企业级应用案例
  • 5G NR学习笔记 预编码(precoding)和波束赋形(beamforming)
  • 嵌入式第三十九天(TCP多任务并发)
  • QT应用层项目20250822
  • MAX系列FPGA型号对比及低功耗特性分析
  • 【Linux 小实战】自定义 Shell 的编写
  • 把CentOS 7默认yum源改成腾讯云镜像
  • 移动端(微信等)使用 vConsole调试console
  • Web漏洞
  • Vue-24-利用Vue3的element-plus库实现树形结构数据展示
  • 一文详解 LangChain4j AiServices:自动代理实现大模型交互
  • 【datawhale组队学习】RAG技术 -TASK05 向量数据库实践(第三章3、4节)
  • 如何使用windows实现与iphone的隔空投送(AirDrop)
  • linux部署overleaf服务器
  • HarmonyOS布局实战:用声明式UI构建自适应电商卡片
  • 华为鸿蒙HarmonyOS Next基础开发教程
  • 【前端】Devtools使用
  • 毕业项目推荐:28-基于yolov8/yolov5/yolo11的电塔危险物品检测识别系统(Python+卷积神经网络)
  • 极限RCE之三字节RCE
  • Go+Gdal 完成高性能GIS数据空间分析