zmalloc出现的目的是将不同的malloc封装起来,从而隐藏不同系统架构下的memory allocation的方法。

    1. //The malloc_size() function returns the size of the memory block that
    2. //backs the allocation pointed to by ptr. The memory block size is always
    3. //at least as large as the allocation it backs, and may be larger.
    4. #define zmalloc_size(p) malloc_size(p)
    5. #define update_zmalloc_stat_alloc(__n) atomicIncr(used_memory,(__n))
    6. /* Allocate memory or panic */
    7. void *zmalloc(size_t size) {
    8. void *ptr = ztrymalloc_usable(size, NULL);
    9. //处理内存不足的错误
    10. if (!ptr) zmalloc_oom_handler(size);
    11. return ptr;
    12. }
    13. /* Try allocating memory, and return NULL if failed.
    14. * '*usable' is set to the usable size if non NULL. */
    15. void *ztrymalloc_usable(size_t size, size_t *usable) {
    16. //分配size+PREFIX_SIZE大小的内存
    17. void *ptr = malloc(size+PREFIX_SIZE);
    18. if (!ptr) return NULL;
    19. #ifdef HAVE_MALLOC_SIZE
    20. size = zmalloc_size(ptr);
    21. update_zmalloc_stat_alloc(size);
    22. if (usable) *usable = size;
    23. return ptr;
    24. #else
    25. //把size存储在阵阵当中
    26. *((size_t*)ptr) = size;
    27. //将allocated size作为静态的全局变量
    28. update_zmalloc_stat_alloc(size+PREFIX_SIZE);
    29. if (usable) *usable = size;
    30. //将指向prefix之后的指针进行返回
    31. return (char*)ptr+PREFIX_SIZE;
    32. #endif
    33. }

    从line 12可以看出,实际上,所申请的内存大小是size+PREFIX_SIZE
    image.png
    这是因为redis会将size的信息作为前缀放入每块申请的内存的前面。

    1. #define update_zmalloc_stat_free(__n) atomicDecr(used_memory,(__n))
    2. void zfree(void *ptr) {
    3. #ifndef HAVE_MALLOC_SIZE
    4. void *realptr;
    5. size_t oldsize;
    6. #endif
    7. if (ptr == NULL) return;
    8. #ifdef HAVE_MALLOC_SIZE
    9. update_zmalloc_stat_free(zmalloc_size(ptr));
    10. free(ptr);
    11. #else
    12. realptr = (char*)ptr-PREFIX_SIZE;
    13. //修正prefix的大小
    14. oldsize = *((size_t*)realptr);
    15. //将已分配的size从静态全局变量中剔除
    16. update_zmalloc_stat_free(oldsize+PREFIX_SIZE);
    17. //释放内存
    18. free(realptr);
    19. #endif
    20. }