redis之zmalloc

号外号外,新建Redis交流讨论群:332160890,欢迎加入!!

zmalloc介绍

这部分是用来申请内存的,之所以单独成了一部分在于redis希望能够将不同系统提供的api统一起来,另外还有一部分系统无法获取malloc数目,因此在这里也进行了一部分的封装;这部分内容很简单,实际上就是malloc, calloc, realloc, free几个操作的变形

代码分析

使用变量

used_memory,已使用的内存数;
malloc_thread_safe,分配内存线程是否安全;
used_memory_mutex,已使用内存数变量互斥锁;

代码分解

zmalloc_default_oom,默认的内存溢出响应函数

static void zmalloc_default_oom(size_t size) {
    fprintf(stderr, "zmalloc: Out of memory trying to allocate %zu bytes\n",
        size);
    fflush(stderr);
    abort();
}

zmalloc,这里面判断是否需要添加prefix_size,也就是将分配的内存大小写到分配内存的前部,根据实际需要大小执行malloc函数

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
}

zcalloc,这个函数与zmalloc的函数区别在于申请得到的内存是否初始化,zcalloc会初始化,zmalloc则是乱数据

void *zcalloc(size_t size) {
    void *ptr = calloc(1, 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
}

zrealloc,这个函数是用来重新分配内存的,如果ptr为空,则直接申请内存即可,如果当前地址不能满足size大小的内存空间,则需要重新申请内存,然后将ptr中数据拷贝过去,返回新申请内存地址;如果当前地址满足,则扩大当前地址范围

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);
    update_zmalloc_stat_alloc(size);
    return (char*)newptr+PREFIX_SIZE;
#endif
}

zfree,释放内存;

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
}

猜你喜欢

转载自blog.csdn.net/fusan2004/article/details/51759101