Source code version: redis 2.4.4
Redis memory-related functions are stored in zmalloc. h zmalloc. C.
Redis can use tcmalloc and jemalloc
Makefile:
ifeq ($(USE_TCMALLOC),yes) ALLOC_DEP= ALLOC_LINK=-ltcmalloc ALLOC_FLAGS=-DUSE_TCMALLOCendififeq ($(USE_JEMALLOC),yes) ALLOC_DEP=../deps/jemalloc/lib/libjemalloc.a ALLOC_LINK=$(ALLOC_DEP) -ldl ALLOC_FLAGS=-DUSE_JEMALLOC -I../deps/jemalloc/includeendif
Zmalloc. c
#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)#endif
Simple Encapsulation
Void * zmalloc (size_t size );
Void * zcalloc (size_t size );
Void * zrealloc (void * PTR, size_t size );
Void zfree (void * PTR );
Simple encapsulation of malloc, calloc, realloc, and free
Analyze zmalloc and zfree
void *zmalloc(size_t size) { void *ptr = malloc(size+PREFIX_SIZE); if (!ptr) zmalloc_oom(size);#ifdef HAVE_MALLOC_SIZE update_zmalloc_stat_alloc(zmalloc_size(ptr),size); return ptr;#else *((size_t*)ptr) = size; update_zmalloc_stat_alloc(size+PREFIX_SIZE,size); return (char*)ptr+PREFIX_SIZE;#endif}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; oldsize = *((size_t*)realptr); update_zmalloc_stat_free(oldsize+PREFIX_SIZE); free(realptr);#endif}
In addition to the specified memory size, prefix_size is also allocated.
The memory pattern is as follows:
Real_ptr returned when applying for memory
#define update_zmalloc_stat_alloc(__n,__size) do { \ size_t _n = (__n); \ if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \ if (zmalloc_thread_safe) { \ pthread_mutex_lock(&used_memory_mutex); \ used_memory += _n; \ pthread_mutex_unlock(&used_memory_mutex); \ } else { \ used_memory += _n; \ } \} while(0)#define update_zmalloc_stat_free(__n) do { \ size_t _n = (__n); \ if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \ if (zmalloc_thread_safe) { \ pthread_mutex_lock(&used_memory_mutex); \ used_memory -= _n; \ pthread_mutex_unlock(&used_memory_mutex); \ } else { \ used_memory -= _n; \ } \} while(0)
Used_memory records the total memory currently allocated
Int vm_max_threads;/* max Number of I/O threads running at the same time */
If (server. vm_max_threads! = 0)
Zmalloc_enable_thread_safeness ();/* We need thread safe zmalloc ()*/
Secure zmalloc is required when threaded virtual memory I/O is used.
size_t zmalloc_used_memory(void) { size_t um; if (zmalloc_thread_safe) pthread_mutex_lock(&used_memory_mutex); um = used_memory; if (zmalloc_thread_safe) pthread_mutex_unlock(&used_memory_mutex); return um;}
Zmalloc_used_memory returns the memory currently used by the process for memory clearing. For example:
Zmalloc_used_memory ()> server. maxmemory // compare with the configured maximum memory ....
Zmalloc_get_rss () is used to calculate the actual physical memory used by the Process