zmalloc.c

版本6.0.1

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; // 用PREFIX_SIZE个bytes记录分配内存的大小
    update_zmalloc_stat_alloc(size+PREFIX_SIZE);
    return (char*)ptr+PREFIX_SIZE; // 返回实际数据的起始地址
#endif
}

通过malloc函数分配内存,malloc根据定义的宏来选择不同的malloc函数。

/* Explicitly override malloc/free etc when using tcmalloc. */
#if defined(USE_TCMALLOC)
#define malloc(size) tc_malloc(size)
#define calloc(count,size) tc_calloc(count,size)
#define realloc(ptr,size) tc_realloc(ptr,size)
#define free(ptr) tc_free(ptr)
#elif defined(USE_JEMALLOC)
#define malloc(size) je_malloc(size)
#define calloc(count,size) je_calloc(count,size)
#define realloc(ptr,size) je_realloc(ptr,size)
#define free(ptr) je_free(ptr)
#define mallocx(size,flags) je_mallocx(size,flags)
#define dallocx(ptr,flags) je_dallocx(ptr,flags)
#endif

比如当定义了USE_TCMALLOC时,使用tc_malloc代替malloc。
以tcmalloc为例,USE_TCMALLOC是定义在Makefile中

# Backwards compatibility for selecting an allocator
ifeq ($(USE_TCMALLOC),yes)
        MALLOC=tcmalloc
endif
ifeq ($(MALLOC),tcmalloc)
        FINAL_CFLAGS+= -DUSE_TCMALLOC
        FINAL_LIBS+= -ltcmalloc
endif

FINAL_CFLAGS等价编译器的CFLAGS

#ifdef HAVE_MALLOC_SIZE
#define PREFIX_SIZE (0)
#else
#if defined(__sun) || defined(__sparc) || defined(__sparc__)
#define PREFIX_SIZE (sizeof(long long))
#else
#define PREFIX_SIZE (sizeof(size_t))
#endif
#endif

宏HAVE_MALLOC_SIZE是在zmalloc.h中定义的,以tcmalloc为例

#if defined(USE_TCMALLOC)
#define ZMALLOC_LIB ("tcmalloc-" __xstr(TC_VERSION_MAJOR) "." __xstr(TC_VERSION_MINOR))
#include <google/tcmalloc.h>
#if (TC_VERSION_MAJOR == 1 && TC_VERSION_MINOR >= 6) || (TC_VERSION_MAJOR > 1)
#define HAVE_MALLOC_SIZE 1
#define zmalloc_size(p) tc_malloc_size(p)
#else
#error "Newer version of tcmalloc required"
#endif

include google/tcmalloc (即gperftools/tcmalloc)
tcmalloc的简单介绍
判断使用的tcmalloc版本,定义宏HAVE_MALLOC_SIZE,zmalloc_size替换为tc_malloc_size
所以在使用tcmalloc时,PREFIX_SIZE为0。

update_zmalloc_stat_alloc是个宏,定义如下

#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)

这里展开后有多行,所以使用do{} while(0)扩起来。
其中的_n变量实际没有用到,以前的版本是使用到的(见github commit)if中的操作是为了按照long类型占用的字节数进行对齐(对2的幂次取余可等价与操作)。atomicIncr见atomicIncr
update_zmalloc_stat_alloc是用来统计内存的分配情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值