preface

The main function of zmalloc.c and zmalloc.h is to encapsulate the memory allocation functions in the original library and form an independent set of memory management functions. Because Redis is cross-platform, and each platform has its own memory management functions, you’ll see a lot of #ifdef in both files, using different memory management functions depending on the system, and the encapsulation interface is the same — Zmalloc. The main functions will be source analyzed below.

update_zmalloc_stat_alloc

The function defined by this macro is to calculate the size of memory currently in use. AtomicIncr is an atomic operation that performs an addition operation, and used_memory is a static variable whose value represents the amount of memory used. The changes to _n before this point were for byte alignment. The macro update_zmalloc_stat_free performs the memory reduction log.

#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)
Copy the code

zmalloc

Zmalloc, ZCalloc, and Zrealloc all treat the original memory management functions the same inside, so we’ll only discuss Zmalloc here.

void *zmalloc(size_t size) { void *ptr = malloc(size+PREFIX_SIZE); //#1 if (! ptr) zmalloc_oom_handler(size); //#2 #ifdef HAVE_MALLOC_SIZE //#3 update_zmalloc_stat_alloc(zmalloc_size(ptr)); //#4 return ptr; #else //#5 *((size_t*)ptr) = size; //#6 update_zmalloc_stat_alloc(size+PREFIX_SIZE); //#7 return (char*)ptr+PREFIX_SIZE; //#8 #endif }Copy the code
  • # 1: If you need to allocate memory, you need to allocate more memoryPREFIX_SIZEBytes are used to record the size of the memory allocation. Some system memory management functions have built-in functions to calculate the allocation of bytes, soPREFIX_SIZESometimes it’s 0.
  • # 2: zmalloc_oom_handlerIs an error handler.
  • # 3and# 4: This is partly because some systems have built-in functions to calculate the size of memory, soPREFIX_SIZE0, just return the pointer.
  • # 5and# 6: When the memory size needs to be calculated manually, the memory size information is stored at the beginning of the pointer.
  • # 7: modifyused_memory.
  • # 8: needs to return the start address of the actual allocated memory, so it needs to addPREFIX_SIZE.

zfree

The memory free function, and zmalloc function operates in reverse. To illustrate the program visually, only the main parts are shown.

void zfree(void *ptr) { ... realptr = (char*)ptr-PREFIX_SIZE; //#1 oldsize = *((size_t*)realptr); update_zmalloc_stat_free(oldsize+PREFIX_SIZE); free(realptr); . }Copy the code
  • # 1: One thing to noteptrPointer cannot be directfreeBecause the size of the actual allocated memory needs to be subtractedPREFIX_SIZE, so it should befreeThe subtracted pointer.

zmalloc_get_rss

The function returns the actual amount of physical memory consumed by the process, which is what RSS means. To illustrate the program visually, only the main parts are shown.

size_t zmalloc_get_rss(void) { int page = sysconf(_SC_PAGESIZE); / / # 1... snprintf(filename,256,"/proc/%d/stat",getpid()); //#2 if ((fd = open(filename,O_RDONLY)) == -1) return 0; if (read(fd,buf,4096) <= 0) { ... } close(fd); p = buf; //#3 count = 23; /* RSS is the 24th field in /proc/<pid>/stat */ while(p && count--) { //#4 p = strchr(p,' '); if (p) p++; } x = strchr(p,' '); *x = '\0'; //#5 rss = strtoll(p,NULL,10); //#6 rss *= page; //#7 return rss; }Copy the code
  • # 1This is a system call where the memory in the system is in pages and the system call returns the size of a page in bytes.
  • # 2:The/proc / < > number pid/statLine 24 of the file holds the RSS of the process.
  • # 3: Reads all contents from a file.
  • # 4 to # 6: basically finds line 24 and then reads the content and converts it to an integer. To understand why I want to do this, I opened a random processstatThe following information is displayed:

So there’s only one between each row' 'Characters are separated. So just find the 24th string and add it at the end\ 0Through thestrtollThe function converts the string to an integer.

  • # 7: The number of pages is multiplied by the size of each page to obtain the physical memory consumption.

end