redis之zmalloc

来源:互联网 发布:火炬红包群 淘宝群 编辑:程序博客网 时间:2024/06/06 02:38

号外号外,新建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}
0 0