您的位置:首页 > 数据库 > Redis

Redis源码分析:内存管理

2015-07-30 11:17 691 查看
源码版本:redis 2.4.4

redis内存相关函数都放在zmalloc.h zmalloc.c中

redis中可以使用tcmalloc、jemalloc
Makefile:

[cpp] view
plaincopy

ifeq ($(USE_TCMALLOC),yes)  

  ALLOC_DEP=  

  ALLOC_LINK=-ltcmalloc  

  ALLOC_FLAGS=-DUSE_TCMALLOC  

endif  

  

ifeq ($(USE_JEMALLOC),yes)  

  ALLOC_DEP=../deps/jemalloc/lib/libjemalloc.a  

  ALLOC_LINK=$(ALLOC_DEP) -ldl  

  ALLOC_FLAGS=-DUSE_JEMALLOC -I../deps/jemalloc/include  

endif  

zmalloc.c中

[cpp] view
plaincopy

#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  

简单封装
void *zmalloc(size_t size);
void *zcalloc(size_t size);
void *zrealloc(void *ptr, size_t size);
void zfree(void *ptr);
分别对malloc、calloc、realloc、free做了简单封装
对zmalloc和zfree做分析

[cpp] view
plaincopy

void *zmalloc(size_t size) {  

    void *ptr = malloc(size+PREFIX_SIZE);  

  

    if (!ptr) zmalloc_oom(size);  

#ifdef HAVE_MALLOC_SIZE  

    update_zmalloc_stat_alloc(zmalloc_size(ptr),size);  

    return ptr;  

#else  

    *((size_t*)ptr) = size;  

    update_zmalloc_stat_alloc(size+PREFIX_SIZE,size);  

    return (char*)ptr+PREFIX_SIZE;  

#endif  

}  

void zfree(void *ptr) {  

#ifndef HAVE_MALLOC_SIZE  

    void *realptr;  

    size_t oldsize;  

#endif  

  

    if (ptr == NULL) return;  

#ifdef HAVE_MALLOC_SIZE  

    update_zmalloc_stat_free(zmalloc_size(ptr));  

    free(ptr);  

#else  

    realptr = (char*)ptr-PREFIX_SIZE;  

    oldsize = *((size_t*)realptr);  

    update_zmalloc_stat_free(oldsize+PREFIX_SIZE);  

    free(realptr);  

#endif  

}  

除了分配给指定大小的内存之外,还分配了PREFIX_SIZE

内存格局如下:



申请内存返回Real_ptr

[cpp] view
plaincopy

#define update_zmalloc_stat_alloc(__n,__size) do { \  

    size_t _n = (__n); \  

    if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \  

    if (zmalloc_thread_safe) { \  

        pthread_mutex_lock(&used_memory_mutex);  \  

        used_memory += _n; \  

        pthread_mutex_unlock(&used_memory_mutex); \  

    } else { \  

        used_memory += _n; \  

    } \  

} while(0)  

  

#define update_zmalloc_stat_free(__n) do { \  

    size_t _n = (__n); \  

    if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \  

    if (zmalloc_thread_safe) { \  

        pthread_mutex_lock(&used_memory_mutex);  \  

        used_memory -= _n; \  

        pthread_mutex_unlock(&used_memory_mutex); \  

    } else { \  

        used_memory -= _n; \  

    } \  

} while(0)  

used_memory记录当前分配的总内存
在定义了 int vm_max_threads; /* Max number of I/O threads running at the same time */
    if (server.vm_max_threads != 0)
        zmalloc_enable_thread_safeness(); /* we need thread safe zmalloc() */
在使用Threaded Virtual Memory I/O的时候,需要安全的zmalloc

[cpp] view
plaincopy

size_t zmalloc_used_memory(void) {  

    size_t um;  

  

    if (zmalloc_thread_safe) pthread_mutex_lock(&used_memory_mutex);  

    um = used_memory;  

    if (zmalloc_thread_safe) pthread_mutex_unlock(&used_memory_mutex);  

    return um;  

}  

zmalloc_used_memory返回进程当前使用的内存,用以做相应的清内存操作,eg:

[cpp] view
plaincopy

zmalloc_used_memory() > server.maxmemory //和配置的最大内存比较  

....  

zmalloc_get_rss()用来计算进程实际使用物理内存
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: