神马是redis?redis是一个开源的,牛B的键值数据库。由于键可以被保存为字符串,列表,哈希表,集合和有序集合,redis有时候也被称作数据结构服务器。这句蹩脚的翻译来自redis官网的介绍。想进一步了解的可以去它官网瞅瞅。目前redis已归入vmware门下。
下面,切入正题。redis是用c编写的。用c编写的程序都要面临一个很重要也很头疼的问题----内存管理。很多时候,不当的内存管理会成为万恶之源。。。redis的内存管理只有两个文件zmalloc.c和zmalloc.h。1 void *zmalloc(size_t size);
2 void *zcalloc(size_t size);
3 void *zrealloc(void *ptr, size_t size);
4 void zfree(void *ptr);
5 char *zstrdup(const char *s);
6 size_t zmalloc_used_memory(void);
7 void zmalloc_enable_thread_safeness(void);
8 float zmalloc_get_fragmentation_ratio(void);
9 size_t zmalloc_get_rss(void);
10 size_t zmalloc_allocations_for_size(size_t size);
11
12 #define ZMALLOC_MAX_ALLOC_STAT 256
1 #ifdef HAVE_MALLOC_SIZE
2 #define PREFIX_SIZE (0)
3 #else
4 #if defined(__sun)
5 #define PREFIX_SIZE (sizeof(long long))
6 #else
7 #define PREFIX_SIZE (sizeof(size_t))
8 #endif
9 #endif
1 /* Use tcmalloc's malloc_size() when available.
2 * When tcmalloc is used, native OSX malloc_size() may never be used because
3 * this expects a different allocation scheme. Therefore, *exclusively* use
4 * either tcmalloc or OSX's malloc_size()! */
5 #if defined(USE_TCMALLOC)
6 #include <google/tcmalloc.h>
7 #if TC_VERSION_MAJOR >= 1 && TC_VERSION_MINOR >= 6
8 #define HAVE_MALLOC_SIZE 1
9 #define redis_malloc_size(p) tc_malloc_size(p)
10 #endif
11 #elif defined(__APPLE__)
12 #include <malloc/malloc.h>
13 #define HAVE_MALLOC_SIZE 1
14 #define redis_malloc_size(p) malloc_size(p)
15 #endif
如果没有malloc_size函数,那么在Solaris系统上,用long long类型的长度来定义PREFIX_SIZE,其他系统为size_t的长度。
接着,定义下面这些宏。这些宏的作用是如果使用tcmalloc库,那么将库中的分配函数对应到标准库上。后面的函数可直接使用标准库函数的名称。在更换库的时候不需要更改。1 /* Explicitly override malloc/free etc when using tcmalloc. */
2 #if defined(USE_TCMALLOC)
3 #define malloc(size) tc_malloc(size)
4 #define calloc(count,size) tc_calloc(count,size)
5 #define realloc(ptr,size) tc_realloc(ptr,size)
6 #define free(ptr) tc_free(ptr)
7 #endif
1 #define update_zmalloc_stat_alloc(__n,__size) do { \
2 size_t _n = (__n); \
3 size_t _stat_slot = (__size < ZMALLOC_MAX_ALLOC_STAT) ? __size : ZMALLOC_MAX_ALLOC_STAT; \
4 if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \
5 if (zmalloc_thread_safe) { \
6 pthread_mutex_lock(&used_memory_mutex); \
7 used_memory += _n; \
8 zmalloc_allocations[_stat_slot]++; \
9 pthread_mutex_unlock(&used_memory_mutex); \
10 } else { \
11 used_memory += _n; \
12 zmalloc_allocations[_stat_slot]++; \
13 } \
14 } while(0)
1 #define update_zmalloc_stat_free(__n) do { \
2 size_t _n = (__n); \
3 if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \
4 if (zmalloc_thread_safe) { \
5 pthread_mutex_lock(&used_memory_mutex); \
6 used_memory -= _n; \
7 pthread_mutex_unlock(&used_memory_mutex); \
8 } else { \
9 used_memory -= _n; \
10 } \
11 } while(0)
1 *((size_t*)ptr) = size;
1 realptr = (char*)ptr-PREFIX_SIZE;
2 oldsize = *((size_t*)realptr);
联系客服