redis之zmalloc

本文介绍了Redis中的zmalloc,其目的是统一不同系统的内存API并管理内存使用情况。内容包括zmalloc的基本功能,如malloc、calloc、realloc和free的变形,并详细分析了used_memory变量、malloc_thread_safe标志及互斥锁等关键元素。此外,文章还探讨了zmalloc、zcalloc、zrealloc和zfree的具体实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

号外号外,新建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
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值