2019独角兽企业重金招聘Python工程师标准>>>

深入redis内部--内存管理 博客分类: 缓存

1. Redis内存管理通过在zmalloc.h和zmalloc.c中重写c语言对内存的管理来完成的。

redis内存管理 c内存管理 原型 作用
zmalloc malloc void *malloc(unsigned int num_bytes); 分配一块指定大小的内存区域,并返回指向该区域头部的指针,分配失败则返回NULL
zcalloc calloc void *calloc(unsigned n, unsigned size); 在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。
zrealloc realloc oid *realloc(void *mem_address, unsigned int newsize); 先判断当前的 指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定 的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域(注意:原来指针是自动释放,不需要使用 free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。
zfree free void free(void *ptr)  释放ptr指向的存储空间。被释放的空间通常被送入可用存储区池,以后可在调用malloc、realloc以及calloc函数来再分配。

封装就是为了屏蔽底层平台的差异,同时方便自己实现相关的统计函数。

定义平台之间的差异,主要是tcmalloc(google)、jemalloc(facebook)、苹果平台。

具体来说就是:

  • 若系统中存在Google的TC_MALLOC库,则使用tc_malloc一族函数代替原本的malloc一族函数。
  • 若系统中存在facebook的JE_MALLOC库,则使用je_malloc一族函数替换原来的malloc一族函数。
  • 若当前系统是Mac系统或者其它系统,则使用<malloc/malloc.h>中的内存分配函数。
/* 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_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

具体如下:

/* Explicitly override malloc/free etc when using tcmalloc. */
#if defined(USE_TCMALLOC)
#define malloc(size) tc_malloc(size)
#define calloc(count,size) tc_calloc(count,size)
#define realloc(ptr,size) tc_realloc(ptr,size)
#define free(ptr) tc_free(ptr)
#elif defined(USE_JEMALLOC)
#define malloc(size) je_malloc(size)
#define calloc(count,size) je_calloc(count,size)
#define realloc(ptr,size) je_realloc(ptr,size)
#define free(ptr) je_free(ptr)
#endif#ifdef HAVE_ATOMIC
#define update_zmalloc_stat_add(__n) __sync_add_and_fetch(&used_memory, (__n))
#define update_zmalloc_stat_sub(__n) __sync_sub_and_fetch(&used_memory, (__n))
#else
#define update_zmalloc_stat_add(__n) do { \pthread_mutex_lock(&used_memory_mutex); \used_memory += (__n); \pthread_mutex_unlock(&used_memory_mutex); \
} while(0)#define update_zmalloc_stat_sub(__n) do { \pthread_mutex_lock(&used_memory_mutex); \used_memory -= (__n); \pthread_mutex_unlock(&used_memory_mutex); \
} while(0)#endif

说明:

Both libraries try to de-contention memory acquire by having threads pick the memory from different caches, but they have different strategies:

  • jemalloc (used by Facebook) maintains a cache per thread
  • tcmalloc (from Google) maintains a pool of caches, and threads develop a "natural" affinity for a cache, but may change

This led, once again if I remember correctly, to an important difference in term of thread management.

  • jemalloc is faster if threads are static, for example using pools
  • tcmalloc is faster when threads are created/destructed

1.1 zmalloc实现

void *zmalloc(size_t size) {void *ptr = malloc(size+PREFIX_SIZE);if (!ptr) zmalloc_oom_handler(size); //如果没有发生内存溢出,则使用的分配方式static void (*zmalloc_oom_handler)(size_t) = zmalloc_default_oom;
#ifdef HAVE_MALLOC_SIZE                  //HAVE_MALLOC_SIZE用来确定系统是否有函数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
}

#define update_zmalloc_stat_alloc(__n) do { \size_t _n = (__n); \if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \if (zmalloc_thread_safe) { \update_zmalloc_stat_add(_n); \} else { \used_memory += _n; \} \
} while(0)#ifdef HAVE_ATOMIC
#define update_zmalloc_stat_add(__n) __sync_add_and_fetch(&used_memory, (__n))
#define update_zmalloc_stat_sub(__n) __sync_sub_and_fetch(&used_memory, (__n))
#else
#define update_zmalloc_stat_add(__n) do { \pthread_mutex_lock(&used_memory_mutex); \used_memory += (__n); \pthread_mutex_unlock(&used_memory_mutex); \
} while(0)#define update_zmalloc_stat_sub(__n) do { \pthread_mutex_lock(&used_memory_mutex); \used_memory -= (__n); \pthread_mutex_unlock(&used_memory_mutex); \
} while(0)#endif

说明

int pthread_mutex_lock(pthread_mutex_t *mutex);

当pthread_mutex_lock()返回时,该互斥锁已被锁定。线程调用该函数让互斥锁上锁,如果该互斥锁已被另一个线程锁定和拥有,则调用该线程将阻塞,直到该互斥锁变为可用为止。

int pthread_mutex_unlock(pthread_mutex_t *mutex);和上面的函数为一对。

其它函数的实现类似。

http://www.cnblogs.com/davidwang456/p/3504563.html

转载于:https://my.oschina.net/xiaominmin/blog/1599663

深入redis内部--内存管理相关推荐

  1. redis 数据结构 内存管理 持久化

    为什么80%的码农都做不了架构师?>>>    Redis 内存数据结构与编码 OBJECT encoding key.DEBUG OBJECT key 简单动态字符串(simple ...

  2. Redis和Memcached的区别(数据类型、内存管理、数据持久化、集群管理)

    Redis的作者Salvatore Sanfilippo曾经对这两种基于内存的数据存储系统进行过比较: Redis支持服务器端的数据操作:Redis相比Memcached来说,拥有更多的数据结构和并支 ...

  3. Redis的持久化机制与内存管理机制

    1.概述 Redis的持久化机制有两种:RDB 和 AOF ,这两种机制有什么区别?正式环境应该采用哪种机制? 我们的服务器内存资源是有限的,如果内存被Redis的缓存占满了怎么办?这就要看Redis ...

  4. 【redismemcached】数据类型、内存管理、数据持久化和集群管理的区别

    这几年redis很火,redis也常常被当做memcached的挑战者被提到桌面上来.关于redis和memcached的比较比比皆是.然而,redis真的在功能.性能以及内存使用效率上都超越memc ...

  5. Redis占用内存过高怎么办

    目录 前言 案例现象 定位问题 内存回收策略 键过期机制 slave的过期策略 解决问题 前言 我们知道,Redis是一个key-value数据库,它的数据是运行在内存中的 其读写效率比将数据存储到磁 ...

  6. BEP 7:CUDA外部内存管理插件(下)

    BEP 7:CUDA外部内存管理插件(下) Numba依赖 向库中添加EMM插件的实现自然会使Numba成为库的依赖项,而以前可能没有.为了使依赖关系可选,如果需要的话,可以有条件地实例化并注册EMM ...

  7. BEP 7:CUDA外部内存管理插件(上)

    BEP 7:CUDA外部内存管理插件(上) 背景和目标 在CUDA阵列接口使得能够共享不同的Python之间的数据库的访问CUDA设备.但是,每个库都与其它库区别对待.例如: • Numba在内部管理 ...

  8. redis的内存会不会耗尽

    我们知道redis使用的资源主要就是内存,那么redis的内存会不会耗尽. 文章目录 概述 设置有效期 过期策略 8种淘汰策略 LRU算法 Redis如何管理热度数据 LFU算法 本文小结 概述 作为 ...

  9. Redis 数据结构与内存管理策略(上)

    Redis 数据结构与内存管理策略(上) 标签: Redis Redis数据结构 Redis内存管理策略 Redis数据类型 Redis类型映射 Redis 数据类型特点与使用场景 String.Li ...

最新文章

  1. Vim的基本操作总结
  2. 回归、插值、逼近、拟合的区别
  3. Kruskal算法的C++语言程序
  4. SPSS 多重共线性问题【SPSS 039期】
  5. 2018icpc ecfinal 西安游记
  6. 爱荷华州立 计算机博士,2020年美国爱荷华州立大学博士全奖招生
  7. 智能家居为什么跑不出“独角兽”?
  8. CentOS 7 iSCSI 多路径(Multipath)配置
  9. MSP430(CCS工程下)添加printf实现打印功能
  10. Axure9的使用经验分享:如何高效的实现弹窗交互模型
  11. maya正交视图锁定与解锁
  12. 杭电考研经验贴———报考计算机专业,慎重!!!
  13. Segmentation Fault 错误原因总结及解决方法
  14. 空间辐射环境 - 银河宇宙线
  15. CSS绘制气泡对话框样式(有边框)
  16. 基于matlab/simulink的交流电机调速系统建模与仿真,基于MATLABSIMULINK的交流电机调速系统建模与仿真...
  17. 《惢客创业日记》2019.02.13(周三) 马云关于诚信的一段视频
  18. 设计引导---不要再盲目的new了!你要学着针对接口编程!(具体方法,Factory,Abstract Factory)...
  19. ids Android xml,Android -- ids.xml文件的使用
  20. servlet接收解析json数据

热门文章

  1. 老张喝茶 教你同步异步 阻塞与非阻塞(转)
  2. shell中符号使用
  3. 2.2. 对网络安全的威胁
  4. 张家界a货翡翠,酒泉a货翡翠
  5. 学号 20172326 《程序设计与数据结构》第三周学习总结
  6. C#中有关数组和string引用类型或值类型的判断
  7. 禁用windows更新完成后的重启提示
  8. 使用C#.NET列举组合数前N项和
  9. 虚拟机常用的内存查看与分析工具
  10. 自定义View实现图片的绘制、旋转、缩放