Redis通过自己的方法管理内存,,主要方法有zmalloc(),zrealloc(), zcalloc()和zfree(), 分别对应C中的malloc(), realloc()、
calloc()和free()。相关代码在zmalloc.h和zmalloc.c中。
Redis自己管理内存的好处主要有两个:可以利用内存池等手段提高内存分配的性能;可以掌握更多的内存信息,以便于Redis虚拟内存(VM)等功能中,决定何时将数据swap到磁盘。
先回忆各个系统中常见的内存分配函数:
malloc()分配一块指定大小的内存区域,并返回指向区域开头的指针,若分配失败,则返回NULL。
calloc()与malloc()一样,分配一块指定大小的内存区域,成功时返回区域头指针,失败返回NULL。

区别在于, calloc()的输入参数为count和size,即分配的项的数
目,及每一项的大小。

calloc()在成功分配内存空间后,会将空间内所有值置0。
realloc()修改已分配的内存块的大小。若已分配的内存块后没有足够的空间用于扩展内存块,则重新申请一块满足需要的内存块,并将旧的数据拷贝到新位置,释放旧的内存块,返回指向新的内存块的指针;否则直接扩展原有的内存块。若分配失败,返回NULL。
free()释放已分配的内存块。
内存分配
在Redis中,如果系统中包含TCMALLOC,则会使用tc_malloc()等TCMALLOC中的方法代替malloc()等原有的分配内存方法。 TCmalloc是google perftools中的一个组件。

#if defined(USE_TCMALLOC)
#define malloc(size) tc_malloc(size)

首先看zmalloc()和zfree()两个最常用的方法。 Redis在申请内存时,除了申请需要的size外,还会多申请一块定长(PREFIX_SIZE)的区域用于记录所申请的内存块的长度。如果申请成功, Redis会使用宏函数(Redis中为性能考虑,大量使用宏函数)
update_zmalloc_stat_alloc(size+PREFIX_SIZE, size)记录申请的内存块的相关信息,以便监控内存使用状况;当内存块被zfree()释放时,根据头部的信息可以快速地获知被释放的内存区域的长度,然后通过宏函数update_zmalloc_stat_free()标记释放。源代码中,若系统支持malloc_size()方法,则会使用它返回指针所指向的内存块的大小(Mac OS X 10.4以上支持该方法[3])。 有疑惑的是,在支持malloc_size()的系统中,为何还要多申请PREFIX_SIZE的内存?

void *zmalloc(size_t size) {void *ptr = malloc(size+PREFIX_SIZE);if (!ptr) zmalloc_oom(size);
#ifdef HAVE_MALLOC_SIZEupdate_zmalloc_stat_alloc(redis_malloc_size(ptr),size);return ptr;
#else*((size_t*)ptr) = size; // 在头部记录内存块的长度update_zmalloc_stat_alloc(size+PREFIX_SIZE,size);return (char*)ptr+PREFIX_SIZE;
#endif
}

宏update_zmalloc_stat_alloc()中,首先将要分配的空间与内存对齐,然后会根据宏zmalloc_thread_safe判断是否需要对内存信息记录表的相关操作加锁。虽然Redis在大部分场景中是单线程读写的,即thread_safe的,但启用虚拟内存(VM),或持久化dump到磁盘等操作时会启动多线程,因此在多线程模式中,需要对部分操作加锁。内存监控
used_memory记录了Redis使用的内存总数。而多线程下malloc()是线程安全的。
zmalloc_allocations[]记录了各个size分配的内存块的数目,大于256个字节的按256算。应用程序可以通过zmalloc_allocations_for_size(size)获得对应size的
内存块的分配数目;也可以通过zmalloc_used_memory()获得Redis占用的总内存。这些监控类的方法在Redis的日志系统中被用到。
zcalloc(size)、 zrealloc()与zmalloc()的处理策略类似,不再详述。
在部分操作系统中, Redis可以通过zmalloc_get_rss()方法获得自己的进程占用
的内存信息。该信息通过操作系统提供,往往比Redis自己记录的used_memory更准确,
但其获取速度也较慢。这些信息也是用于虚拟内存功能。
除了内存相关的操作外, Redis在此还提供了一个复制字符串的方法zstrdup(char
*),该方法将申请一块与源字符串长度相同的内存区域,并用memcpy()拷贝字符串的内
容。

redis——内存概述相关推荐

  1. redis删除过期key的算法_面试官别再问我Redis内存满了该怎么办了

    概述 Redis的文章,我之前写过一篇关于「Redis的缓存的三大问题」,累计阅读也快800了,对于还只有3k左右的粉丝量,能够达到这个阅读量,已经是比较难了. 这说明那篇文章写的还过得去,收到很多人 ...

  2. 一文深入了解 Redis 内存模型,Redis 的快是有原因的!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:编程迷思 cnblogs.com/kismetv/p/865 ...

  3. 别再问我Redis内存满了该怎么办了

    概述 Redis的文章,我之前写过一篇关于「Redis的缓存的三大问题」,累计阅读也快800了,对于还只有3k左右的粉丝量,能够达到这个阅读量,已经是比较难了. 这说明那篇文章写的还过得去,收到很多人 ...

  4. redis 内存不足 排查_一文深入了解 Redis 内存模型,Redis 的快是有原因的!

    前言 一.Redis内存统计 二.Redis内存划分 1.数据 2.进程本身运行需要的内存 3.缓冲内存 4.内存碎片 三.Redis数据存储的细节 1.概述 2.jemalloc 3.redisOb ...

  5. redis 内存不足 排查_Redis 系统学习之 redis 内存模型

    关注:架构师学习路线,每日更新互联网最新技术文章与你不断前行,实战资料,笔试面试 前言 Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站高并 ...

  6. 可能是目前最详细的Redis内存模型及应用解读

    Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站高并发不可或缺的一部分. 我们使用Redis时,会接触Redis的5种对象类型:字符串.哈希 ...

  7. 文带你深入了解 Redis 内存模型

    前言 Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站高并发不可或缺的一部分. 我们使用Redis时,会接触Redis的5种对象类型(字符串 ...

  8. 深入学习Redis(1):Redis内存模型

    前言 Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站高并发不可或缺的一部分. 我们使用Redis时,会接触Redis的5种对象类型(字符串 ...

  9. Redis之Redis内存模型

    Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站高并发不可或缺的一部分. 我们使用Redis时,会接触Redis的5种对象类型(字符串.哈希 ...

最新文章

  1. 让GBDT和GNN结合起来:Criteo AI Lab提出全新架构BGNN
  2. SAP HUM 因为存在Open TO 单据使得HU不能创建盘点凭证
  3. html css移动位置,html – 如何使用CSS移动对象?
  4. img 标签 点击跳出图层_你竟然不知道cad图层也可以导出与导入?
  5. 解决React Native报错:Error:Found unexpected optical bounds (red pixel)
  6. 按小时分组mysql 补齐_分组记录按小时或按天白天和mysql的
  7. 大一python编程题_请教python编程问题(作业就剩这几道题了)
  8. I00017 生成9开头的按位递减数
  9. allure 测试报告本地打开_Allure自动化测试报告我是这样用的
  10. Linux学习(2)常用的命令
  11. linux vsftpd 配置及使用详解
  12. 多功能工具箱微信小程序源码
  13. Javascript基础——函数
  14. Verilog语法误区总结
  15. KITTI Odometry数据集处理:将全局pose转换为帧间pose转换
  16. 【SLAM学习】(三)激光雷达原理及分类
  17. [LTE 资源分配方法]资源池 resource pools
  18. R语言manova函数多元方差分析(MANOVA)、单因素多元方差分析的两个假设是多元正态性和方差-协方差矩阵的齐性、QQ图评估多元正态性、mvoutlier包中的aq.plot函数检验多变量异常值
  19. 面对新的挑战,成为更好的自己--进击的技术er
  20. ubuntu串口调试工具kermit和minicom

热门文章

  1. python 定义变量_第三章(第2节):变量和常量
  2. java rpg项目代码_java rpg游戏代码(移动保存读取)
  3. MinGW编译boost库
  4. linux eclipse 头文件路径,Eclipse CDT标准库头文件设置
  5. PHP实训笔记,【学习笔记19】实验吧 让我进去
  6. python的map怎么用_python中的map怎么使用
  7. 上位机与1200组态步骤_组态王与 I/O 设备
  8. 【转】DICOM的常用Tag分类和说明!!!!
  9. 微软认证及课程简写含义
  10. 【转】深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第四节 参数传递对堆栈的影响 2