美文网首页
学习redis源码(1):redis的内存管理

学习redis源码(1):redis的内存管理

作者: 三分钟热度的陈恤猿 | 来源:发表于2019-08-11 23:03 被阅读0次

           内存分配的代码写在zmalloc.c和zmalloc.h中。原理是对底层内存分配方式的再封装。除此之外,redis没有对内存进行额外的操作,因此,内存分配器的性能和碎片化率会对redis造成一些性能上的影响。其底层内存分配会根据宏的选择不同而有所不同。如果定义了USE_TCMALLOC,则使用tcmalloc;如果定义了USE_JEMALLOC,则使用jemalloc;否则如果系统自带c运行库,将会使用系统自带的malloc进行内存分配;最后才会使用redis自己的内存分配函数。
    redis会通过定义宏 HAVE_MALLOC_SIZE为1 来表示使用的是其他库的内存分配函数。
           封装的底层函数:

    malloc_usable_size(p)//返回p对应内存的大小
    malloc(size)//分配堆内存,内容没有初始化
    calloc(count,size)//在malloc基础上,将内存初始化为0
    realloc(ptr,size)
    free(ptr)
    

           对于特定版本的JEMALLOC,redis实现了内存的碎片化处理。

           zmalloc里主要的两个宏

    #define update_zmalloc_stat_alloc(__n) do { \
        size_t _n = (__n); \
        if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \
        atomicIncr(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)); \
        atomicDecr(used_memory,__n); \
    

           上面两个都进行了原子操作,保证线程安全;同时if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)) 确保了64位机上8字节对齐(这个技巧运用了位操作,效率很高;同时字节对齐的单位取决于系统,即所谓的软编码)。
           zmalloc里的重要变量:

    static size_t used_memory = 0;
    pthread_mutex_t used_memory_mutex = PTHREAD_MUTEX_INITIALIZER;
    static void (*zmalloc_oom_handler)(size_t) = zmalloc_default_oom;
    

           zmalloc主要函数如下:

    size_t zmalloc_usable(void *ptr)//返回内存大小(不包含prefix的大小)
    size_t zmalloc_size(void *ptr)//返回内存大小(包含prefix的大小)
    void *zmalloc(size_t size);
    void *zcalloc(size_t size);
    void *zrealloc(void *ptr, size_t size);
    void zfree(void *ptr);
    char *zstrdup(const char *s);
    size_t zmalloc_used_memory(void);
    void zmalloc_set_oom_handler(void (*oom_handler)(size_t));
    //获得系统的配置信息
    size_t zmalloc_get_rss(void);//实际使用的物理内存
    size_t zmalloc_get_smap_bytes_by_field(char *field, long pid);//得到指定pid指定field对应的值
    size_t zmalloc_get_private_dirty(long pid);//上一个函数的filed为”Private_Dirty"
    int zmalloc_get_allocator_info(size_t *allocated, size_t *active, size_t *resident);//得到已经申请了内存数,活跃的,长期存在的内存数
    size_t zmalloc_get_memory_size(void);//获得RAM的大小
    

           redis的内存分配方式如下:



           prefix存储buf的大小。这种管理方式类似redis中的sds管理方式。如果使用了外部库的内存分配函数,PREFIX_SIZE为0。

    相关文章

      网友评论

          本文标题:学习redis源码(1):redis的内存管理

          本文链接:https://www.haomeiwen.com/subject/grecjctx.html