redis内存分配分析

2024-06-15 00:48
文章标签 分析 内存 分配 redis

本文主要是介绍redis内存分配分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

简述

redis的内存分配相关的代码存储与zmalloc.hzmalloc.c之中,整体的分配策略非常的简单,需要额外注意HAVE_MALLOC_SIZE这个宏

zmalloc.h

在这里,一开始让我很疑惑的是开头的这一系列条件编译

#if defined(USE_TCMALLOC)#define ZMALLOC_LIB ("tcmalloc-" __xstr(TC_VERSION_MAJOR) "." __xstr(TC_VERSION_MINOR))#include <google/tcmalloc.h>#if (TC_VERSION_MAJOR == 1 && TC_VERSION_MINOR >= 6) || (TC_VERSION_MAJOR > 1)#define HAVE_MALLOC_SIZE 1#define zmalloc_size(p) tc_malloc_size(p)#else#error "Newer version of tcmalloc required"#endif#elif defined(USE_JEMALLOC)#define ZMALLOC_LIB ("jemalloc-" __xstr(JEMALLOC_VERSION_MAJOR) "." __xstr(JEMALLOC_VERSION_MINOR) "." __xstr(JEMALLOC_VERSION_BUGFIX))#include <jemalloc/jemalloc.h>#if (JEMALLOC_VERSION_MAJOR == 2 && JEMALLOC_VERSION_MINOR >= 1) || (JEMALLOC_VERSION_MAJOR > 2)#define HAVE_MALLOC_SIZE 1#define zmalloc_size(p) je_malloc_usable_size(p)#else#error "Newer version of jemalloc required"#endif#elif defined(__APPLE__)#include <malloc/malloc.h>#define HAVE_MALLOC_SIZE 1#define zmalloc_size(p) malloc_size(p)
#endif

后来认真啃了下网上相关的文章才明白了,redis根据这一系列的条件编译,来决定使用哪种内存分配方案,即tcmalloc,jemalloc,malloc(Apple)。第三个的mallocOS X系统。
可以注意到,在条件编译中, redis均定义了HAVE_MALLOC_SIZE这个宏。原因是,这三种内存分配方案都提供了计算所分配内存大小的函数,如果不使用这三种方案,单纯的使用C自带的malloc的话,需要自己去倒腾计算内存大小的函数。redis将这三种内存分配方案中计算内存大小的函数都换成了统一的zmalloc_size。这也是为了方便以后的使用

zmalloc.c

这里便是内存分配的实现了,花了我好一阵时间去啃,redis确实用到了蛮厉害的技巧。
首先该文件引用了config.hpthread.h俩头文件,config.h包含了一些跨平台的宏,pthread.h则包含了多进程所需锁。

#ifdef HAVE_MALLOC_SIZE#define PREFIX_SIZE (0)
#else#if defined(__sun) || defined(__sparc) || defined(__sparc__)#define PREFIX_SIZE (sizeof(long long))#else#define PREFIX_SIZE (sizeof(size_t))#endif
#endif

需要重点关注的便是这里所出现的宏了。HAVE_MALLOC_SIZE这个宏如果被定义过了,说明使用了内存分配方案中有mallloc_size这个函数,能够给出分配的内存大小,否则redis定义了PREFIX_SIZE这一变量,该变量用于在分配内存时,额外的划分一段内存,用于存储本次所分配的内存大小。
其次是used_memory这一静态变量,该变量用于存储进程所占用的内存大小,每次对内存进行增删的时候,都使用宏来修改该值。使用宏而不使用函数,估计是为了增加运行效率。

  • 增加内存时,使用update_zmalloc_stat_alloc来增加used_memory的值
  • 减少内存时,使用update_zmalloc_stat_free来减少used_memory的值

在这俩函数中,需要额外注意的是

if (_n&(sizeof(long)-1))_n += sizeof(long)-(_n&(sizeof(long)-1));

其中if用于判断本次内存的变化量是否是long类型大小的整数倍,如果不是,则进行一个对齐处理,而后通过update_zmalloc_stat_add安全的增加used_memory的值。

函数实现

redis有俩实现分配内存的函数,分别是zmalloczcalloc,这俩函数看名字就知道区别了。
在分配内存的时候,除了分配参数所要求的大小的内存外,还需额外的分配上文提到的PREFIX_SIZE大小的内存空间,如果定义了HAVE_MALLOC_SIZE
PREFIX_SIZE的值是0,不需要偏移。如果使用的是C自带的malloc,还需要额外的一小步工作

    *((size_t*)ptr) = size;update_zmalloc_stat_alloc(size+PREFIX_SIZE);return (char*)ptr+PREFIX_SIZE;

通过第一条语句,将指针所指的地方(此时还在开头),存放本次内存分配的大小,而后去更新used_memory。记得返回值要偏移PREFIX_SIZE个字节
如果使用C自带的malloc,则还需要额外的定义一个自己的zmalloc_size
在搞懂上述一个函数之后,其他的函数便不难理解了。
zmalloc_used_memory这个函数用于返回进程所占用的内存大小,要注意到获取used_memory时,都有上一个锁,推测是是为了防止在获取大小的时候,其他进程修改了值。
最后需要注意的是zmalloc_get_rss这个函数用于返回实际占用的物理内存大小,由注释可以看出,这是通过特定的系统调用获取到准确的内存占用。
具体的可以参考这篇博文写的十分清楚。此外zmalloc_get_private_dirty也同样直接参考该博文即可。

这篇关于redis内存分配分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1061961

相关文章

NameNode内存生产配置

Hadoop2.x 系列,配置 NameNode 内存 NameNode 内存默认 2000m ,如果服务器内存 4G , NameNode 内存可以配置 3g 。在 hadoop-env.sh 文件中配置如下。 HADOOP_NAMENODE_OPTS=-Xmx3072m Hadoop3.x 系列,配置 Nam

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57

衡石分析平台使用手册-单机安装及启动

单机安装及启动​ 本文讲述如何在单机环境下进行 HENGSHI SENSE 安装的操作过程。 在安装前请确认网络环境,如果是隔离环境,无法连接互联网时,请先按照 离线环境安装依赖的指导进行依赖包的安装,然后按照本文的指导继续操作。如果网络环境可以连接互联网,请直接按照本文的指导进行安装。 准备工作​ 请参考安装环境文档准备安装环境。 配置用户与安装目录。 在操作前请检查您是否有 sud

线性因子模型 - 独立分量分析(ICA)篇

序言 线性因子模型是数据分析与机器学习中的一类重要模型,它们通过引入潜变量( latent variables \text{latent variables} latent variables)来更好地表征数据。其中,独立分量分析( ICA \text{ICA} ICA)作为线性因子模型的一种,以其独特的视角和广泛的应用领域而备受关注。 ICA \text{ICA} ICA旨在将观察到的复杂信号

【软考】希尔排序算法分析

目录 1. c代码2. 运行截图3. 运行解析 1. c代码 #include <stdio.h>#include <stdlib.h> void shellSort(int data[], int n){// 划分的数组,例如8个数则为[4, 2, 1]int *delta;int k;// i控制delta的轮次int i;// 临时变量,换值int temp;in

三相直流无刷电机(BLDC)控制算法实现:BLDC有感启动算法思路分析

一枚从事路径规划算法、运动控制算法、BLDC/FOC电机控制算法、工控、物联网工程师,爱吃土豆。如有需要技术交流或者需要方案帮助、需求:以下为联系方式—V 方案1:通过霍尔传感器IO中断触发换相 1.1 整体执行思路 霍尔传感器U、V、W三相通过IO+EXIT中断的方式进行霍尔传感器数据的读取。将IO口配置为上升沿+下降沿中断触发的方式。当霍尔传感器信号发生发生信号的变化就会触发中断在中断

kubelet组件的启动流程源码分析

概述 摘要: 本文将总结kubelet的作用以及原理,在有一定基础认识的前提下,通过阅读kubelet源码,对kubelet组件的启动流程进行分析。 正文 kubelet的作用 这里对kubelet的作用做一个简单总结。 节点管理 节点的注册 节点状态更新 容器管理(pod生命周期管理) 监听apiserver的容器事件 容器的创建、删除(CRI) 容器的网络的创建与删除