版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、redis实现细节之:”zmalloc“函数之前在为 eufa 添加本地缓存管理的功能时,基本的数据存储功能用法了容易的双向链表来实现,但因为在 wasm32 架构上的最大可用内存惟独 4gb,因此我们需要对本地内存的用法大小做一个限制,但如何才干够精确地获得应用所用法的内存大小呢?我们都知道,譬如 malloc 等标准库中的内存分配函数会按照当前的系统架构类型自动地举行4/8字节的内存对齐,因此对于应用在存储数据时底层系统实际分配的内存大小我们很难挺直举行计算。 而为了解决这个问题,在这里我挺直借鉴了 redis 在其内存管理上的实现方式。如下所示,我们挺直来看 redis 源码(不是最新版
2、本)中自定义的 zmalloc 函数,该函数与 malloc 等常规函数的用法方式彻低全都,不同的在于其内部的详细实现详情。 void *zmalloc(size_t size) / 分配内存; void *ptr = malloc(size + prefix_size); / 分配失败抛出异样; if (!ptr) zmalloc_oom_handler(size); / 系统是否可以用法malloc_size函数? ifdef have_malloc_size update_zmalloc_stat_alloc(zmalloc_size(ptr); return ptr; else / 在
3、数据域保存分配数据的实际大小; *(size_t*)ptr) = size; / 计算对齐后的内存用法大小,并更新used_memory变量; update_zmalloc_stat_alloc(size + prefix_size); / 返回数据体的初始位置; return (char*)ptr + prefix_size; endif 其实,标准库中的 malloc 函数已经能够自动为分配的内存实现对齐,因此 zmalloc 办法在这里其主要目的是为了能够精确地计算每一次数据存储时所分配的内存大小。在每一次分配内存时,zmalloc 都会在该次分配的数据内存大小的基础上再加上一个 pre
4、fix_size 大小的额外内存空间,这个 prefix_size 宏代表了当前系统的最大内存寻址空间大小(size_t),其依靠于详细系统的类型不同而不同。这里我们可以简称这个 prefix_size 大小的空间为一个存储单元的数据头部分。 初版 redis 的存储单元结构 如上图所示,通过 *(size_t*)ptr) = size; 语句,redis 在当前分配内存块的前 prefix_size 个字节,即数据头内存储了本次实际分配的数据块大小,而在后面 size 大小的内存空间中才真正存放了二进制的数据实体。在这里名为 update_zmalloc_stat_alloc 的函数在其内部
5、会维护一个名为 used_memory 的全局变量,该变量累加了每次新分配的内存大小。函数在最后返回了一个偏移的指针,指向了当前分配内存的数据体部分。update_zmalloc_stat_alloc 函数的详细实现详情如下。 define update_zmalloc_stat_alloc(_n) do size_t _n = (_n); / 手动内存补齐; if (_n&(sizeof(long)-1) _n += sizeof(long)-(_n&(sizeof(long)-1); atomicincr(used_memory, _n); while(0)
6、 这里需要注重的重点是 _n += sizeof(long)-(_n&(sizeof(long)-1); 这行语句。囫囵宏函数首先推断本次分配的内存大小是否为 sizeof(long) 大小的整数倍(64位机对应着8字节的内存对齐;32位机则对应着4字节的内存对齐),假如不是则通过我们之前给出的语句在该数据段后添加相应的占位空间来补足位数以满足内存对齐(4/8字节)的要求。最后的 atomicincr 函数用来在保证线程平安的状况下更新全局的 used_memory 变量值。 而该版本 redis 中内存释放与其内存分配的过程则正巧相反。如下所示代码为对应 zfree 函数的实
7、现详情。首先该函数通过 (char*)ptr-prefix_size 语句(向内存低地址移动)指向了包含有该数据块实际占用大小的数据域首地址,然后通过 *(size_t*)realptr) 语句获得到了该数据块分配的真切内存大小(不包含内存对齐区域)。最后再通过 update_zmalloc_stat_free 函数来更新全局变量 used_memory 的值,并释放该段内存。 void zfree(void *ptr) ifndef have_malloc_size void *realptr; size_t oldsize; endif if (ptr = null) return; if
8、def have_malloc_size update_zmalloc_stat_free(zmalloc_size(ptr); free(ptr); else realptr = (char*)ptr-prefix_size; oldsize = *(size_t*)realptr); update_zmalloc_stat_free(oldsize+prefix_size); free(realptr); endif 如下所示,这里假如我们再来看 update_zmalloc_stat_free 函数的实现详情,你会发觉它与之前的 update_zmalloc_stat_alloc 函数其
9、执行过程类似。通过计算需要补足的内存字节大小,并从 used_memory 变量中减去相应大小的内存空间,即可实现对内存空间用法率的精确计算。 define update_zmalloc_stat_free(_n) do size_t _n = (_n); if (_n&(sizeof(long)-1) _n += sizeof(long)-(_n&(sizeof(long)-1); atomicdecr(used_memory,_n); while(0) 最后再来认真回顾一下刚刚我们在 update_zmalloc_stat_alloc 函数中执行内存补齐操作的部分。在 wasm32 架构中,sizeof(long) 的值是4,因此对应的补齐操作语句就变成了 if(_n&3) _n += 4 - (_n&3);,即需要满足4字节对齐。假如此时用户端有一个大小为13字节的数据需要存储,那么经过内存对齐处理,应用实际存放到内存中的数据大小便为:13+4-1=16字节大小,内存对齐字节的计算过程可以参考下图。 内存对齐字节计算流程 以上便是 redis 在其整体复杂设计实现过程中的一个非常细小但却精妙的设计点。ps:函数 atomicdec
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 中山市博爱医院2026年人才招聘49人备考题库及参考答案详解一套
- 5G+AI辅助重症患者个体化治疗策略
- 2026年广州医科大学附属口腔医院招聘备考题库(一)完整答案详解
- 3D打印人工皮肤的美学与功能重建
- 2025年义乌市胜利幼儿园招聘备考题库及参考答案详解1套
- 2025年改则县审计局面向社会公开聘用编外工程师备考题库及一套答案详解
- 简约中国风地产营销策划方案
- 项目高处作业施工方案
- 2025年厦门市集美区乐安小学非在编教师招聘备考题库及答案详解1套
- 2025年四川省岳池银泰投资(控股)有限公司公开招聘急需紧缺专业人才备考题库有答案详解
- 2025年及未来5年市场数据中国旧楼加装电梯市场供需现状及投资战略数据分析研究报告
- 院内感染暴发应急响应全流程
- caac机长证考试内容
- 转移性副神经节瘤和嗜铬细胞瘤诊治专家共识2026
- 2025年秋小学音乐湘艺版四年级上册期末测试卷含答案
- 2025年山东省考公务员面试题(监狱警察)及解析
- 国家公园休闲管理
- 2025年教师招聘考试教育综合知识6000题(主观题含答案)
- 基于生成对抗网络的图像修复与超分辨率-洞察及研究
- 广东省惠州市2025届高三下学期4月模拟考试化学
- 二十届四中全会开启中国经济新篇章研究制定十五五规划建议
评论
0/150
提交评论