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

RapidJSON 自定义内存分配器详解与实战

前言

RapidJSON 是一个高性能的 C++ JSON 解析/生成库,其默认使用 MallocAllocator —— 即直接调用 malloc/free 进行内存分配。在大多数场景下这完全够用。
但在高性能、低延迟、高并发或嵌入式环境中,频繁调用系统级 malloc/free 会带来:内存碎片化、分配/释放性能瓶颈、缓存不友好等问题
RapidJSON 从设计之初就支持 Allocator 模板参数,允许你“插拔”任意符合接口的内存管理器,真正做到“零成本抽象”。

一、标题rapidjson源码分析

#define RAPIDJSON_DEFAULT_ALLOCATOR ::RAPIDJSON_NAMESPACE::MemoryPoolAllocator<::RAPIDJSON_NAMESPACE::CrtAllocator>
//...省略
template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR >
class GenericValue {
public://! Name-value pair in an object.typedef GenericMember<Encoding, Allocator> Member;typedef Encoding EncodingType;                  //!< Encoding type from template parameter.typedef Allocator AllocatorType;                //!< Allocator type from template parameter.typedef typename Encoding::Ch Ch;               //!< Character type derived from Encoding.typedef GenericStringRef<Ch> StringRefType;     //!< Reference to a constant stringtypedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterator MemberIterator;  //!< Member iterator for iterating in object.typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator;  //!< Constant member iterator for iterating in object.typedef GenericValue* ValueIterator;            //!< Value iterator for iterating in array.typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.typedef GenericValue<Encoding, Allocator> ValueType;    //!< Value type of itself.typedef GenericArray<false, ValueType> Array;typedef GenericArray<true, ValueType> ConstArray;typedef GenericObject<false, ValueType> Object;typedef GenericObject<true, ValueType> ConstObject;///...省略

通过rapidjson::GenericValue代码分析得出,GenericValue 是可以使用自定义的Allocator 分配器的,其默认为RAPIDJSON_DEFAULT_ALLOCATOR ,而这个宏又指向名为CrtAllocator的类

#ifndef RAPIDJSON_MALLOC
///! customization point for global \c malloc
#define RAPIDJSON_MALLOC(size) std::malloc(size)
#endif
#ifndef RAPIDJSON_REALLOC
///! customization point for global \c realloc
#define RAPIDJSON_REALLOC(ptr, new_size) std::realloc(ptr, new_size)
#endif
#ifndef RAPIDJSON_FREE
///! customization point for global \c free
#define RAPIDJSON_FREE(ptr) std::free(ptr)
#endif//..........省略//! C-runtime library allocator.
/*! This class is just wrapper for standard C library memory routines.\note implements Allocator concept
*/
class CrtAllocator {
public:static const bool kNeedFree = true;void* Malloc(size_t size) { if (size) //  behavior of malloc(0) is implementation defined.return RAPIDJSON_MALLOC(size);elsereturn NULL; // standardize to returning NULL.}void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {(void)originalSize;if (newSize == 0) {RAPIDJSON_FREE(originalPtr);return NULL;}return RAPIDJSON_REALLOC(originalPtr, newSize);}static void Free(void *ptr) RAPIDJSON_NOEXCEPT { RAPIDJSON_FREE(ptr); }bool operator==(const CrtAllocator&) const RAPIDJSON_NOEXCEPT {return true;}bool operator!=(const CrtAllocator&) const RAPIDJSON_NOEXCEPT {return false;}
};

CrtAllocator类为C++申请内存的默认方式(malloc、realloc、free)
由此得出结论,仅需要自定义实现一个CrtAllocator类似的类,即可自定义rapidjson的内存分配器

class MyAllocator {
public:static const bool kNeedFree = true; // 是否需要显式释放内存void* Malloc(size_t size);void* Realloc(void* originalPtr, size_t originalSize, size_t newSize);void Free(void* ptr);
};

二、应用举例

1.以提高内存使用效率、减少碎片为目的

通过我的另外一篇文章QT基于mmap文件映射机制实现的内存池方法总结,实现自定义内存申请方式,即可将json数据映射到磁盘或其他储存中,减少内存的占用

2.性能分析、内存泄漏检测等场景

class CrtAllocatorWithStats {
public:static const bool kNeedFree = true;size_t totalAllocated = 0;size_t totalFreed = 0;size_t peakUsage = 0;void* Malloc(size_t size) {void* ptr = std::malloc(size);if (ptr) {totalAllocated += size;peakUsage = std::max(peakUsage, totalAllocated - totalFreed);}return ptr;}void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {void* ptr = std::realloc(originalPtr, newSize);if (ptr) {if (newSize > originalSize) {totalAllocated += (newSize - originalSize);} else {totalFreed += (originalSize - newSize);}peakUsage = std::max(peakUsage, totalAllocated - totalFreed);}return ptr;}void Free(void* ptr) {if (ptr) {// 注意:无法知道释放了多少字节,除非记录分配表(略复杂)// 此处简化处理totalFreed += 1; // 仅计数次数}std::free(ptr);}
};

通过重写Allocator并在内存释放、申请等位置计数或计时,就能对此性能进行分析

三、总结

自定义内存分配器是 RapidJSON 高性能的“隐藏武器”,它让你在内存控制、性能优化、场景适配上拥有极大的自由度。虽然大多数项目用默认分配器就够了,但在游戏、高频交易、嵌入式、服务端网关等场景,一个精心设计的 Allocator 能带来数倍性能提升和更低的延迟波动。
欢迎点赞、收藏、转发!

http://www.dtcms.com/a/398023.html

相关文章:

  • 深度学习-PyTorch 模型
  • WPF依赖属性学习
  • 云原生-高级阶段-利用rsync备份全网服务器数据
  • wordpress建购物网站抚顺营销型网站建设
  • Pythoner 的Flask项目实践-添加Shapefile面数据并展示功能Mapboxgl底图
  • Flutter混合Android开发Release 打包失败GeneratedPluginRegistrant.java,Plugin不存在
  • docker 安装TDengine 并创建新用户
  • 网站推广实施方案珠海网站制作软件
  • 为世界添彩 - WebGL 中的颜色与着色器变量
  • 初识MYSQL —— mysql的安装
  • c回顾 01
  • 【LeetCode 每日一题】3484. 设计电子表格——(解法一)二维数组
  • python+django/flask+springboot实践性教学系统 实训任务发布 学生作业提交 教师评阅管理系统
  • 洞悉未来,智驭不确定性:蒙特卡洛模拟决策模型实践
  • 长宁哪里有做网站优化比较好利润在100万到300万之间税率2021
  • 沈阳网站设计外包广西建设网官网桂建云
  • vscode 插件怎么实现编辑器行号处添加图标标记
  • Git 从零到一:以 Gitee 为例的实战与可视化指南
  • React 标准 SPA 项目 入门学习记录
  • HAProxy 完整指南:简介、负载均衡原理与安装配置
  • 领码课堂 | React 核心组件与高级性能优化全实战指南
  • 涡轮丝杆升降机的丝杆材质有哪些?
  • 前端笔记:vue中 Map、Set之间的使用和区别
  • 中美关系最新消息视频重庆seo优化公司
  • 【Cesium 开发实战教程】第六篇:三维模型高级交互:点击查询、材质修改与动画控制
  • 英雄联盟视频网站源码做产品设计之前怎么查资料国外网站
  • Vue3-接入飞书H5应用
  • 四川省建设厅网站川北医学院广告网站怎么建设
  • 七彩喜智慧养老:科技向善,让晚年生活绽放“喜”悦之光
  • 模型驱动的 AI Agent架构:亚马逊云科技的Strands框架技术深度解析