From 399f2f401c6fc3d489e2e40ffc78638425e3a09e Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sat, 24 Jul 2010 23:20:00 +0200 Subject: [PATCH] Add zcalloc and use it where appropriate calloc is more effecient than malloc+memset when the system uses mmap to allocate memory. mmap always returns zeroed memory so the memset can be avoided. The threshold to use mmap is 16k in osx libc and 128k in bsd libc and glibc. The kernel can lazily allocate the pages, this reduces memory usage when we have a page table or hash table that is mostly empty. This change is most visible when you start a new redis instance with vm enabled. You'll see no increased memory usage no matter how big your page table is. --- src/dict.c | 6 ++---- src/vm.c | 3 +-- src/zmalloc.c | 14 ++++++++++++++ src/zmalloc.h | 1 + 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/dict.c b/src/dict.c index 0d4aacb7..77ce90cb 100644 --- a/src/dict.c +++ b/src/dict.c @@ -148,14 +148,12 @@ int dictExpand(dict *d, unsigned long size) if (dictIsRehashing(d) || d->ht[0].used > size) return DICT_ERR; + /* Allocate the new hashtable and initialize all pointers to NULL */ n.size = realsize; n.sizemask = realsize-1; - n.table = zmalloc(realsize*sizeof(dictEntry*)); + n.table = zcalloc(realsize*sizeof(dictEntry*)); n.used = 0; - /* Initialize all the pointers to NULL */ - memset(n.table, 0, realsize*sizeof(dictEntry*)); - /* Is this the first initialization? If so it's not really a rehashing * we just set the first hash table so that it can accept keys. */ if (d->ht[0].table == NULL) { diff --git a/src/vm.c b/src/vm.c index 073cace2..0ccc5fe2 100644 --- a/src/vm.c +++ b/src/vm.c @@ -86,10 +86,9 @@ void vmInit(void) { } else { redisLog(REDIS_NOTICE,"Swap file allocated with success"); } - server.vm_bitmap = zmalloc((server.vm_pages+7)/8); + server.vm_bitmap = zcalloc((server.vm_pages+7)/8); redisLog(REDIS_VERBOSE,"Allocated %lld bytes page table for %lld pages", (long long) (server.vm_pages+7)/8, server.vm_pages); - memset(server.vm_bitmap,0,(server.vm_pages+7)/8); /* Initialize threaded I/O (used by Virtual Memory) */ server.io_newjobs = listCreate(); diff --git a/src/zmalloc.c b/src/zmalloc.c index 8658376a..5c1b5e9a 100644 --- a/src/zmalloc.c +++ b/src/zmalloc.c @@ -89,6 +89,20 @@ void *zmalloc(size_t size) { #endif } +void *zcalloc(size_t size) { + void *ptr = calloc(1, size+PREFIX_SIZE); + + if (!ptr) zmalloc_oom(size); +#ifdef HAVE_MALLOC_SIZE + increment_used_memory(redis_malloc_size(ptr)); + return ptr; +#else + *((size_t*)ptr) = size; + increment_used_memory(size+PREFIX_SIZE); + return (char*)ptr+PREFIX_SIZE; +#endif +} + void *zrealloc(void *ptr, size_t size) { #ifndef HAVE_MALLOC_SIZE void *realptr; diff --git a/src/zmalloc.h b/src/zmalloc.h index 193e7eda..db858bba 100644 --- a/src/zmalloc.h +++ b/src/zmalloc.h @@ -32,6 +32,7 @@ #define _ZMALLOC_H void *zmalloc(size_t size); +void *zcalloc(size_t size); void *zrealloc(void *ptr, size_t size); void zfree(void *ptr); char *zstrdup(const char *s); -- 2.47.2