Redis源码zmalloc内存管理(2)

zmalloc.c redis内存管理篇源码分析 PREFIX_SIZE说明 在zmalloc函数中,实际可能会每次多申请一个 PREFIX_SIZE的空间。从如下的代码中看出,如果定义了宏HAVE_MALLOC_SIZE,那么 PREFIX_SIZE的长度为0。其他的情况下,都会多分配至少8字节的长度的内存空间 #ifdef HAVE_MALLOC_SIZE #define PREFIX_SIZE (0) #else #if defined(_... 阅读详情

zmalloc内存管理(2)(Redis源码学习)

1. 背景介绍

在上一篇zmalloc内存管理(1)中留了一个问题,在 zmalloc 函数中用出现了条件编译,涉及到是否定义 HAVE_MALLOC_SIZE:

#ifdef HAVE_MALLOC_SIZE
    update_zmalloc_stat_alloc(zmalloc_size(ptr));
    return ptr;
#else
    *((size_t*)ptr) = size;
    update_zmalloc_stat_alloc(size+PREFIX_SIZE);
    return (char*)ptr+PREFIX_SIZE;
#endif

如果你所使用的环境编译redis时,根据所在Linux编译环境会检测到是否定义 HAVE_MALLOC_SIZE,然后决定执行时走哪一部分代码。
下面就 HAVE_MALLOC_SIZE 进行相关介绍。

2. 编译选项

下面是redis对应src目录下面的Makefile文件中的部分片段,进行说明

uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')

# Default allocator
ifeq ($(uname_S),Linux)
	MALLOC=jemalloc
else
	MALLOC=libc
endif

# Backwards compatibility for selecting an allocator
ifeq ($(USE_TCMALLOC),yes)
	MALLOC=tcmalloc
endif

ifeq ($(USE_TCMALLOC_MINIMAL),yes)
	MALLOC=tcmalloc_minimal
endif

ifeq ($(USE_JEMALLOC),yes)
	MALLOC=jemalloc
endif

uname_S 那一句就是执行sh命令,在RHEL6.9中然后得出变量uname_S值为Linux,可以将改行括号里的命令直接拷贝到Linux命令行进行执行,就能看到结果。

接下来是条件判断语句,如果 uname_S 值等于 Linux,则将变量 MALLOC 赋值为 jemalloc(shell脚本中的变量是直接使用的),反之则为libc。

说明:

我在编译Redis-3.0 时,直接make报错失败,所以当时就按照 README 文件中的命令 make MALLOC=libc 能编译通过。文中说 jemalloc 是Linux系统中默认的内存分配方式,因为 jemalloc 进行内存操作,产生的内存碎片比较少。学习Redis源码开始时,主要是看内部实现细节,可以先以源码为主,屡清大概流程,至于内测分配方式,等对Redis源码阅读的差不多,架构等环节清楚后,再来研究这些细节。

后面的 ifeq 条件判断,都是针对不同的内存分配方式,来给予 MALLOC 不同的值。

3. zmalloc内存分配方式

上面2中的makefile中的相关变量值,会影响到后续zmalloc的源码条件编译选项,这样就能屏蔽Redis不同运行平台的差异,方便不同平台复用相同的函数。

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

#ifndef ZMALLOC_LIB
#define ZMALLOC_LIB "libc"
#endif 
...
#ifndef HAVE_MALLOC_SIZE
size_t zmalloc_size(void *ptr);
#endif

针对上面这段宏的预处理,可以得知:

(1). 若系统存在 TCMALLOC,那就定义 ZMALLOC_LIB,并包含相应的头文件,内存相关操作函数就直接使用TCMALLOC。
(2). 若系统存在 JEMALLOC,,那就定义 JEMALLOC_LIB,并包含相应的头文件,内存相关操作函数就直接使用JEMALLOC。
(3). 若系统是苹果,则直接使用 malloc/malloc.h 中的相关函数操作内存。
(4). 其它情况,在每一段分配好的空间前头,同时多分配一个定长的字段,用来记录分配的空间大小。 

tc_malloc是google开源处理的一套内存管理库,是用C++实现的,jemalloc 也是一个内存创管理库,jemalloc聚集了malloc的使用过程中所验证的很多技术。

可能你有疑问系统不是有了malloc 吗,为什么还有这样的内存管理库?? 由于经典的libc的分配器碎片率为较高,下面第二链接的文章对比了上面几个内存分配方式的碎片率对比。
文中大概结论:采用tcmalloc时碎片率是最低的,为1.01,jemalloc为1.02,而libc的分配器碎片率为1.31,仅供参考,如有兴趣,可以自行验证。

目前是学习Redis源码阶段,可以先不用关心内存分配方式,先能成功编译安装Redis,调试源码,学习验证代码是最重要的,等后续可以再验证不同内存分配方式下Redis的表现。

另外针对malloc和free,有一定的缺陷,主要记录两点:

(1). 频繁调用malloc,free会造成大量内存碎片,无法回收重新利用,造成内存使用率低。
(2). 作为系统调用,其系统开销远远大于一般函数。

本人才疏学浅,理解水平有限,如果有错误及不当之处,请批评指正。

如果对您有一点点帮助,请帮忙转发和关注工作号:hongmaolinux,感激不尽_!

参考链接:
https://blog.youkuaiyun.com/daniel_ustc/article/details/26478995

https://www.jb51.net/article/100575.htm

https://blog.youkuaiyun.com/jisuanji198509/article/details/115393116

在这里插入图片描述

浅谈redis采用不同内存分配器tcmalloc和jemalloc 我们知道Redis并没有自己实现内存池,没有在标准的系统内存分配器上再加上自己的东西。所以系统内存分配器的性能及碎片率会对Redis造成一些性能上的影响。 在Redis的 zmalloc.c 源码中,我们可以看到如下代码: /* Double expansion needed for stringification of macro values. */ #define __xstr(s) __str(s) #define __str(s) #s #if defined(USE_TCMALLOC) #define ZMALLOC_LIB ("tcmalloc-" __xstr(TC_VERS 立即下载

相关推荐

MiniMax H3 + ComfyUI 工作流搭建指南:从整合包到视频生成

AI视频生成正成为内容创作的新基础设施,而ComfyUI作为可视化工作流引擎,将复杂的模型推理过程拆解为节点与连线,让本地视频生成变得可复用、可批量。理解这一原理后,用户无需编写代码,只需掌握模型加载、提示词控制、采样与解码的基本链路,即可搭建出稳定的视频生产管线。MiniMax H3作为前沿视频生成模型,在ComfyUI中通过权重文件和自定义节点落地,配合整合包可大幅降低环境配置门槛。从硬件评估、目录结构到节点连接与参数调优,本文系统性梳理了从零跑通一条视频生成工作流的完整路径,帮助用户在批量素材生成、风

weixin_29057065的博客 415

shell程序中 2> /dev/null 代表什么意思?

作者:裕用ID 链接:https://www.zhihu.com/question/53295083/answer/135258024 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 以下来自一个重度linux使用患者不请自来的回答。 先用简单的语言回答题主的问题: shell程序中 2> /dev/null 代表什么意思? 答:“2> /dev/null” 代表忽略掉错误提示信息。 如题 2> 代表什么意思?讲错误输出删除? 答:“2&g.

glenshappy的专栏 1万+

SDFCOM_SWC警告深度剖析:从assign短路到时序标注失效的链路追踪

本文深入剖析了SDFCOM_SWC警告的根源,从assign短路到时序标注失效的全链路追踪。通过分析RTL设计中的assign语句陷阱、综合阶段的优化变形以及PrimeTime生成SDF文件的视角,提出了重构RTL设计、警告抑制和SDF生成优化等解决方案,帮助工程师有效避免时序标注问题。

weixin_42519985的博客 365

使用Redis中skiplist的例子

使用Redis中skiplist的例子

dreamcs的专栏 960

CANdelaStudio实战:如何用19服务快速编辑DTC快照数据(附Excel模板)

本文详细介绍了在CANdelaStudio中利用19服务高效编辑DTC快照数据的进阶技巧。通过导出DTC池至Excel进行批量编辑,结合‘Copy from DTC Pool’功能实现配置复用,并分享了构建自定义Excel模板与字段映射的实用方法,帮助工程师将繁琐的手动配置转化为工程化的批量处理,大幅提升诊断数据库开发效率。

weixin_29230773的博客 192

实战篇| app爬虫不用真机

之前写过一篇基于真机app爬虫《App爬虫实战篇-以华为真机手机爬取集换社的app为例》,如果大家有用真机爬虫的经历,会深刻认识到真的不方便,一是自己的手机,经常会被电话、微信等打断,二是闲置手机,面对小批量数据还能勉强,大批量爬虫,会导致成本指数级上升,并且控制起来相对麻烦。以下就是常见的模拟器。emulator -avd my_avd -no-snapshot-save # 启动时不保存 snapshot。emulator -avd my_avd -wipe-data # 清除数据(恢复到出厂)

youbingchen的博客 597

Shell标准输出、标准错误 >/dev/null 2>&1

eg:sudo kill -9 ps -elf |grep -v grep|grep $1|awk '{print $4}' 1>/dev/null 2>/dev/null 命令的结果可以通过%>的形式来定义输出 /dev/null 代表空设备文件 代表重定向到哪里,例如:echo “123” > /home/123.txt 1 表示stdout标准输出,系统默认值是1,...

Neo 1万+

风电功率预测 | 基于RF随机森林的风电功率预测(附matlab完整源码)

风电功率预测 | 基于RF随机森林的风电功率预测(附matlab完整源码)

天天酷科研的博客 896

linux中Shell标准输出错误 >/dev/null 2>&1 分析

Shell中可能经常能看到:>/dev/null  2>&1     eg:sudo kill -9 `ps -elf |grep -v grep|grep $1|awk '{print $4}'` 1>/dev/null 2>/dev/null 命令的结果可以通过%>的形式来定义输出 /dev/null 代表空设备文件     > 代表重定向到哪里,例如:echo "123" > /ho

程序狗的成长之路 1408

论文翻译:arxiv-2023 Do-Not-Answer: A Dataset for Evaluating Safeguards in LLMs

随着大型语言模型(LLMs)的快速发展,出现了新的、难以预测的有害能力。这要求开发者能够通过评估“危险能力”来识别风险,以便负责任地部署LLMs。在这项工作中,我们收集了第一个开源数据集,用于评估LLMs中的安全保障,并以低成本部署更安全的开源LLMs。我们的数据集经过策划和筛选,只包含负责任的语言模型不应遵循的指令。我们注释并评估了六个流行的LLMs对这些指令的响应。基于我们的注释,我们继续训练了几个类似BERT的分类器,并发现这些小型分类器在自动安全评估上能够取得与GPT-4相当的成果。

CSPhD-winston的博客 1132

【雷达】一维和二维自适应波束形成(DBF))DBF附matlab代码

1 简介 数字波束形成技术是天线波束形成原理与数字信号处理技术相结合的产物,其广泛应用于阵列信号处理领域.由于电磁工作环境的恶化和大量射频干扰的存在,在极低的信干噪比(SINR)条件下进行目标检测和信息提取十分困难.对于阵列系统,往往采用自适应数字波束形成(ADBF)技术,来抑制强干扰和方向性干扰对有用信号的影响.介绍了数字波束形成器的基本原理及其DSP的实现结构.​ 2 完整代码 clc;clear all;close all;%%%%%%%%%%%%%%%%%一维DBF%%%%%%%%%%%%%

qq_59747472的博客 7267

Redis底层详解(三) 内存管理

一、内存分配概述 redis 的内存分配,实质上是对 tcmalloc / jemalloc 的封装。内存分配本质就是给定需要分配的大小,以字节为单位,然后返回一个指向一段分配好的连续的内存空间的首指针。 通过这个首指针,我们需要知道它的连续空间的大小,才能进行内存统计,某些低版本的 tcmalloc / jemalloc 不支持通过给定指针获取它申请的内存块...

英雄哪里出来 29万+

【Agent】AI Agent架构趋势及演进

本文系统介绍了AI Agent架构的发展趋势和技术框架,涵盖单Agent与多Agent系统设计、提示词工程与上下文管理、SpringAI开发框架等关键技术。重点阐述了AI原生应用参考架构,包括Nacos配置管理、Higress AI网关、RocketMQ会话状态管理等核心组件解决方案。同时深入探讨了AI应用可观测性体系,包含OpenTelemetry全链路追踪、关键指标监控以及基于LoongSuite开源工具的数据采集评估方法,为构建高效可靠的AI应用提供了全景式技术参考。

一个内容严谨、方向前沿、极具实践价值的AI大模型技术分享站 1106

Redis源码分析:内存管理

源码版本:redis 2.4.4 redis内存相关函数都放在zmalloc.h zmalloc.c中 redis中可以使用tcmalloc、jemalloc Makefile: [cpp] view plain copy ifeq ($(USE_TCMALLOC),yes)     ALLOC_DEP=     ALLOC_LINK=

Golden_lion的博客 347

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Screenpipe 3 步跑通:本地 AI 桌面助手从克隆到搜索

Screenpipe 是一个本地 AI 桌面助手。它持续录屏、录音频,数据全程存在你本机,再把这些上下文交给 AI 智能体(替你执行任务的 AI 程序)。记录的是屏幕文字、音频和按键事件,不是每秒视频。支持 macOS、Windows 与 Linux,离线也能用。 录制状态一览,数据都在本机。 [![screenpipe 本地录制状态](https://raw.gitcode.com/GitH

gitblog_00817的博客 519

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

【redis 源码学习】空间配置(zmalloc)

要学习redis的架构,摆在眼前的,就是空间配置器,所以,第一篇学习,我就先把这座山挪开!!! 一定是可以实现的!!!

看,未来的博客 4973

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

[redis 源码走读] - zmalloc

作者简介:大家好,我是哥,前中兴通讯、美团架构师,现某互联网公司联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬学习必须往深处挖,挖的越深,基础越扎实!jemalloctcmalloclibc其中jemalloctcmalloc是第三方的实现,libc的实现做了一些简单的封装。

smart_an的专栏 945

zmalloc内存管理(1)(Redis源码学习)

zmalloc内存管理(1)(Redis源码学习) 在学习sds.c源码时,sdsnewlen函数中开始调用zmalloc相关库函数: sds sdsnewlen(const void *init, size_t initlen) { ... //省略部分代码 // 根据是否有初始化内容,选择适当的内存分配方式 // T = O(N) if (init) { // zmalloc 不初始化所分配的内存 sh = zmalloc(sizeof(

highmaple的博客 513

Redis内存管理的基石zmallc.c源码解读(一)

当我第一次阅读了这个文件的源码的时候,我笑了,因为我忽然想起前几周阿里电话二面的时候,问到了自定义内存管理函数并涉及8字节对齐问题。当时无言以对,在面试官无数次的提示下才答了出来,结果显而易见,挂掉了二面。而这份源码中函数zmalloc()和zfree()的设计思路和实现原理,正是面试官想要的答案。 本文详细介绍该文件下几个主要函数:zmalloc()、zfree()、zcalloc()、zrealloc()、zstrdup()的源码。

果冻虾仁 1万+

redis zmalloc

zmalloc Redis现在的版本可以支持使用tcmalloc或者是jemalloc或是apple的malloc,或者是Redis自己的zmalloc。zmalloc对内存的分配管理是线程安全的(static size_t used_memory = 0;变量用来记录已经使用的内存空间的大小),而且分配的内存必须要求是以sizeof(long)对其的。 源码 zmalloc.hzmal

chengkun199059的专栏 1359

5分钟搞懂Redis内存管理核心:zmalloc如何让你的缓存飞起来

Redis作为高性能的内存数据库,其闪电般的速度很大程度上归功于高效的内存管理机制。而在Redis的内存管理体系中,zmalloc模块扮演着至关重要的角色,它不仅是内存分配的入口,更是实现内存使用监控和优化的核心组件。本文将带你快速了解zmalloc的工作原理,以及它如何让你的Redis缓存性能飙升。 ## 为什么Redis需要zmalloc? 在标准C语言的内存分配函数(malloc、cal

gitblog_01003的博客 476

Redis源码4.0阅读日记 (1)内存管理 zmalloc

Redis源码4.0阅读 之 内存管理 zmalloc 本文分析了 Redis 的 zmalloc.c 和 zmalloc.h 代码 全文注释,分析实现

Leon的博客 861

Redis3.0源码学习笔记(一)——zmalloc.c文件

持续更新中… zmalloc.c源码阅读笔记源码内容宏源码分析update_zmalloc_stat_alloc() & update_zmalloc_stat_free()update_zmalloc_stat_add() & update_zmalloc_stat_sub()函数源码分析zmalloc()zcalloc()zrealloc()zfree()zstrdup() 源码内容 主要函数 功能简述 zmalloc() 分配内存,但不初始化 zfree() 清理z

weixin_38942728的博客 3832

Redis 内存管理 源码分析

要想了解redis底层的内存管理是如何进行的,直接看源码绝对是一个很好的选择下面是我添加了详细注释的源码,需要注意的是,为了便于源码分析,我把redis为了弥补平台差异的那部分代码删了,只需要知道有这个东西便好下面我会贴上两份源码:一份是我自己的,有删减添加了注释的,一部分是原生的,可以做个参考对照redis内存管理部分的源码在zmalloc.h文件和zmalloc.c文件推荐文章:h...

Y先森0.0 186

Redis源码学习(三)--内存管理zmalloc.c

源码结构 zmalloc.c文件的内容如下: 主要函数 zmalloc() zfree() zcalloc() zrelloc() zstrdup() 字长与字节对齐 CPU一次性能读取数据的二进制位数称为字长,也就是我们通常所说的32位系统(字长4个字节)、64位系统(字长8个字节)的由来。所谓的8字节对齐,就是指变量的起始地址是8的倍数。比如程序运行时(CPU)在读取long型数据的时候,只需要一个总线周期,时间更短,如果不是8字节对齐的则需要两个总线周期才能读完数据。...

qq_20853741的博客 747

Redis 3.0源码分析-内存分配zmalloc

Redis默认的内存分配器采用jemalloc,可选的分配器还有:glibc、tcmalloc。内存分配器为了更好地管理和重复利用内存,分配内存策略一般采用固定范围的内存块进行分配。例如jemalloc在64位系统中将内存空间划分为:小、大、巨大三个范围。每个范围内又划分为多个小的内存单元,如下所示: 小:[8 byte],[16 byte, 32 byte, 48 byte, …, 128 b...

肥叔菌的博客 9520
上一篇: zmalloc内存管理(1)(Redis源码学习)
下一篇: Redis源码sds学习三
highmaple
博客等级 码龄16年 0粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值