redis阅读 - zmalloc.c

zmalloc.c文件中主要是内存分配一些操作,其中主要是对C语言内存分配函数进行了一定封装,加上了一些其他的功能(如统计,异常处理等等)。总体来说还是十分简单的

zmalloc&zcalloc

在redis中,zmalloc函数是对系统malloc的一种封装。增加了内存统计的功能

以下是zmalloc函数的源代码

至于zrealloc,跟zmalloc十分类似,在此就不赘言了。

void *zmalloc(size_t size) {
    
    void *ptr = malloc(size+PREFIX_SIZE);
//如果分配失败的话,则使用异常处理函数
    if (!ptr) zmalloc_oom_handler(size);
   //申请完毕后,将会做内存统计。
#ifdef HAVE_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
}
//附
//这里宏函数先对__n变量进行了对于long的内存对齐,后使用原子操作增加used_memory
#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)

//同理,这个是一旦free内存后,继续更新的统计的操作,同样加入了对其。
#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); \
} while(0)



zrealloc

//realloc函数
void *zrealloc(void *ptr, size_t size) {
#ifndef HAVE_MALLOC_SIZE
    void *realptr;
#endif
    size_t oldsize;
    void *newptr;
//如果指针为NULL的话,那么realloc相当于alloc。所以直接调用zmalloc函数即可
    if (ptr == NULL) return zmalloc(size);

//如果定义了HAVE_MALLOC_SIZE宏的话,就先将以前分配的内存直接清零,然后直接重新分配
#ifdef HAVE_MALLOC_SIZE
    oldsize = zmalloc_size(ptr);
    newptr = realloc(ptr,size);
    if (!newptr) zmalloc_oom_handler(size);

    update_zmalloc_stat_free(oldsize);		//减去oldsize
    update_zmalloc_stat_alloc(zmalloc_size(newptr));	//加入new的size
    return newptr;

//如果不是的话,就先找到内存的起始点,然后重新分配
#else
    realptr = (char*)ptr-PREFIX_SIZE;
    oldsize = *((size_t*)realptr);
    newptr = realloc(realptr,size+PREFIX_SIZE);
    if (!newptr) zmalloc_oom_handler(size);

    *((size_t*)newptr) = size;
    update_zmalloc_stat_free(oldsize+PREFIX_SIZE);
    update_zmalloc_stat_alloc(size+PREFIX_SIZE);
    return (char*)newptr+PREFIX_SIZE;
#endif
}
//free函数,本质上就是调用了free函数,同时更新了内存统计数据
void *zrealloc(void *ptr, size_t size) {
#ifndef HAVE_MALLOC_SIZE
    void *realptr;
#endif
    size_t oldsize;
    void *newptr;

    if (ptr == NULL) return zmalloc(size);
#ifdef HAVE_MALLOC_SIZE
    oldsize = zmalloc_size(ptr);
    newptr = realloc(ptr,size);
    if (!newptr) zmalloc_oom_handler(size);

    update_zmalloc_stat_free(oldsize);
    update_zmalloc_stat_alloc(zmalloc_size(newptr));
    return newptr;
#else
    realptr = (char*)ptr-PREFIX_SIZE;
    oldsize = *((size_t*)realptr);
    newptr = realloc(realptr,size+PREFIX_SIZE);
    if (!newptr) zmalloc_oom_handler(size);

    *((size_t*)newptr) = size;
    update_zmalloc_stat_free(oldsize+PREFIX_SIZE);
    update_zmalloc_stat_alloc(size+PREFIX_SIZE);
    return (char*)newptr+PREFIX_SIZE;
#endif
}

你可能感兴趣的:(redis)