zmalloc出现的目的是将不同的malloc封装起来,从而隐藏不同系统架构下的memory allocation的方法。
//The malloc_size() function returns the size of the memory block that
//backs the allocation pointed to by ptr. The memory block size is always
//at least as large as the allocation it backs, and may be larger.
#define zmalloc_size(p) malloc_size(p)
#define update_zmalloc_stat_alloc(__n) atomicIncr(used_memory,(__n))
/* Allocate memory or panic */
void *zmalloc(size_t size) {
void *ptr = ztrymalloc_usable(size, NULL);
//处理内存不足的错误
if (!ptr) zmalloc_oom_handler(size);
return ptr;
}
/* Try allocating memory, and return NULL if failed.
* '*usable' is set to the usable size if non NULL. */
void *ztrymalloc_usable(size_t size, size_t *usable) {
//分配size+PREFIX_SIZE大小的内存
void *ptr = malloc(size+PREFIX_SIZE);
if (!ptr) return NULL;
#ifdef HAVE_MALLOC_SIZE
size = zmalloc_size(ptr);
update_zmalloc_stat_alloc(size);
if (usable) *usable = size;
return ptr;
#else
//把size存储在阵阵当中
*((size_t*)ptr) = size;
//将allocated size作为静态的全局变量
update_zmalloc_stat_alloc(size+PREFIX_SIZE);
if (usable) *usable = size;
//将指向prefix之后的指针进行返回
return (char*)ptr+PREFIX_SIZE;
#endif
}
从line 12可以看出,实际上,所申请的内存大小是size+PREFIX_SIZE
这是因为redis会将size的信息作为前缀放入每块申请的内存的前面。
#define update_zmalloc_stat_free(__n) atomicDecr(used_memory,(__n))
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;
//修正prefix的大小
oldsize = *((size_t*)realptr);
//将已分配的size从静态全局变量中剔除
update_zmalloc_stat_free(oldsize+PREFIX_SIZE);
//释放内存
free(realptr);
#endif
}