Commit 399f2f40 authored by Benjamin Kramer's avatar Benjamin Kramer
Browse files

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.
parent d9dd352b
...@@ -148,14 +148,12 @@ int dictExpand(dict *d, unsigned long size) ...@@ -148,14 +148,12 @@ int dictExpand(dict *d, unsigned long size)
if (dictIsRehashing(d) || d->ht[0].used > size) if (dictIsRehashing(d) || d->ht[0].used > size)
return DICT_ERR; return DICT_ERR;
/* Allocate the new hashtable and initialize all pointers to NULL */
n.size = realsize; n.size = realsize;
n.sizemask = realsize-1; n.sizemask = realsize-1;
n.table = zmalloc(realsize*sizeof(dictEntry*)); n.table = zcalloc(realsize*sizeof(dictEntry*));
n.used = 0; 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 /* 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. */ * we just set the first hash table so that it can accept keys. */
if (d->ht[0].table == NULL) { if (d->ht[0].table == NULL) {
......
...@@ -86,10 +86,9 @@ void vmInit(void) { ...@@ -86,10 +86,9 @@ void vmInit(void) {
} else { } else {
redisLog(REDIS_NOTICE,"Swap file allocated with success"); 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", redisLog(REDIS_VERBOSE,"Allocated %lld bytes page table for %lld pages",
(long long) (server.vm_pages+7)/8, server.vm_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) */ /* Initialize threaded I/O (used by Virtual Memory) */
server.io_newjobs = listCreate(); server.io_newjobs = listCreate();
......
...@@ -89,6 +89,20 @@ void *zmalloc(size_t size) { ...@@ -89,6 +89,20 @@ void *zmalloc(size_t size) {
#endif #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) { void *zrealloc(void *ptr, size_t size) {
#ifndef HAVE_MALLOC_SIZE #ifndef HAVE_MALLOC_SIZE
void *realptr; void *realptr;
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#define _ZMALLOC_H #define _ZMALLOC_H
void *zmalloc(size_t size); void *zmalloc(size_t size);
void *zcalloc(size_t size);
void *zrealloc(void *ptr, size_t size); void *zrealloc(void *ptr, size_t size);
void zfree(void *ptr); void zfree(void *ptr);
char *zstrdup(const char *s); char *zstrdup(const char *s);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment