深入redis内部--内存管理
来源:互联网 发布:综合开发研究院知乎 编辑:程序博客网 时间:2024/05/17 23:28
1. Redis内存管理通过在zmalloc.h和zmalloc.c中重写c语言对内存的管理来完成的。
封装就是为了屏蔽底层平台的差异,同时方便自己实现相关的统计函数。
定义平台之间的差异,主要是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 threadtcmalloc
(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 poolstcmalloc
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);和上面的函数为一对。
其它函数的实现类似。
0 0
- 深入redis内部--内存管理
- 深入redis内部--实现字符串
- 深入redis内部--字典实现
- 深入redis内部---网络编程
- 深入redis内部--初始化服务器
- 深入Redis内部-Redis 源码讲解
- 深入Redis内部-Redis 源码讲解
- redis 内存管理
- Redis内存管理
- redis 内存管理zmalloc
- 深入redis内部--实现双向链表
- 深入redis内部--字典实现(未完成)
- 深入redis内部--事件处理机制
- 内存管理深入研究
- 深入JVM-内存管理
- 深入Linux内存管理
- 深入内存管理
- 深入redis内部之redis启动过程之一
- How Religion Destroys Programmers--ref
- 让插入到 innerHTML 中的 script 跑起来的代码
- weblogic cluster error-----Could not= open connection with host: 127.0.0.1
- 13走了,14来了,新的一年,新的开始。
- weblogic JDBC Connection Pools--转官方文档
- 深入redis内部--内存管理
- redis虚拟内存---官方文档
- 深入redis内部--事件处理机制
- 华邦外贸经验谈:如何有效进行报关手续
- SVN命令行怎么用?--转百度知道
- 并查集uva1160
- How to Install Eclipse C/C++ Development Tool--转
- 用C语言实现Ping程序功能---转
- ping 原理与ICMP协议---转