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_SIZEsize = 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_SIZEvoid *realptr;size_t oldsize;#endifif (ptr == NULL) return;#ifdef HAVE_MALLOC_SIZEupdate_zmalloc_stat_free(zmalloc_size(ptr));free(ptr);#elserealptr = (char*)ptr-PREFIX_SIZE;//修正prefix的大小oldsize = *((size_t*)realptr);//将已分配的size从静态全局变量中剔除update_zmalloc_stat_free(oldsize+PREFIX_SIZE);//释放内存free(realptr);#endif}
