From a3e60027e7d4419971406c6da7d6e8accbcaf9b0 Mon Sep 17 00:00:00 2001
From: antirez <antirez@gmail.com>
Date: Tue, 2 Nov 2010 11:50:55 +0100
Subject: [PATCH] Now maxmemory, VM, and everything else uses the fast RSS
 memory used estimation instead of raw memory reported by zmalloc(). This
 means that setting maxmemory to 2GB will really have the effect of using up
 to 2GB of memory.

---
 src/aof.c   |  4 ++--
 src/rdb.c   |  6 +++---
 src/redis.c | 24 +++++++++++-------------
 3 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/src/aof.c b/src/aof.c
index 4dbce394c..dffe95ed9 100644
--- a/src/aof.c
+++ b/src/aof.c
@@ -280,11 +280,11 @@ int loadAppendOnlyFile(char *filename) {
 
         /* Handle swapping while loading big datasets when VM is on */
         force_swapout = 0;
-        if ((zmalloc_used_memory() - server.vm_max_memory) > 1024*1024*32)
+        if ((redisEstimateRSS() - server.vm_max_memory) > 1024*1024*32)
             force_swapout = 1;
 
         if (server.vm_enabled && force_swapout) {
-            while (zmalloc_used_memory() > server.vm_max_memory) {
+            while (redisEstimateRSS() > server.vm_max_memory) {
                 if (vmSwapOneObjectBlocking() == REDIS_ERR) break;
             }
         }
diff --git a/src/rdb.c b/src/rdb.c
index a401a5b9d..b8e24ab6d 100644
--- a/src/rdb.c
+++ b/src/rdb.c
@@ -885,16 +885,16 @@ int rdbLoad(char *filename) {
 
         /* Flush data on disk once 32 MB of additional RAM are used... */
         force_swapout = 0;
-        if ((zmalloc_used_memory() - server.vm_max_memory) > 1024*1024*32)
+        if ((redisEstimateRSS() - server.vm_max_memory) > 1024*1024*32)
             force_swapout = 1;
 
         /* If we have still some hope of having some value fitting memory
          * then we try random sampling. */
         if (!swap_all_values && server.vm_enabled && force_swapout) {
-            while (zmalloc_used_memory() > server.vm_max_memory) {
+            while (redisEstimateRSS() > server.vm_max_memory) {
                 if (vmSwapOneObjectBlocking() == REDIS_ERR) break;
             }
-            if (zmalloc_used_memory() > server.vm_max_memory)
+            if (redisEstimateRSS() > server.vm_max_memory)
                 swap_all_values = 1; /* We are already using too much mem */
         }
     }
diff --git a/src/redis.c b/src/redis.c
index 99ff1898b..d28a423ed 100644
--- a/src/redis.c
+++ b/src/redis.c
@@ -545,7 +545,7 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
         redisLog(REDIS_VERBOSE,"%d clients connected (%d slaves), %zu bytes in use",
             listLength(server.clients)-listLength(server.slaves),
             listLength(server.slaves),
-            zmalloc_used_memory());
+            redisEstimateRSS());
     }
 
     /* Close connections of timedout clients */
@@ -590,9 +590,7 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
     /* Swap a few keys on disk if we are over the memory limit and VM
      * is enbled. Try to free objects from the free list first. */
     if (vmCanSwapOut()) {
-        while (server.vm_enabled && zmalloc_used_memory() >
-                server.vm_max_memory)
-        {
+        while (server.vm_enabled && redisEstimateRSS() > server.vm_max_memory) {
             int retval;
 
             if (tryFreeOneObjectFromFreelist() == REDIS_OK) continue;
@@ -600,7 +598,7 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
                         vmSwapOneObjectBlocking() :
                         vmSwapOneObjectThreaded();
             if (retval == REDIS_ERR && !(loops % 300) &&
-                zmalloc_used_memory() >
+                redisEstimateRSS() >
                 (server.vm_max_memory+server.vm_max_memory/10))
             {
                 redisLog(REDIS_WARNING,"WARNING: vm-max-memory limit exceeded by more than 10%% but unable to swap more objects out!");
@@ -940,7 +938,7 @@ int processCommand(redisClient *c) {
      * is returning an error. */
     if (server.maxmemory) freeMemoryIfNeeded();
     if (server.maxmemory && (cmd->flags & REDIS_CMD_DENYOOM) &&
-        zmalloc_used_memory() > server.maxmemory)
+        redisEstimateRSS() > server.maxmemory)
     {
         addReplyError(c,"command not allowed when used memory > 'maxmemory'");
         return REDIS_OK;
@@ -1059,7 +1057,7 @@ sds genRedisInfoString(void) {
     getrusage(RUSAGE_SELF, &self_ru);
     getrusage(RUSAGE_CHILDREN, &c_ru);
 
-    bytesToHuman(hmem,zmalloc_used_memory());
+    bytesToHuman(hmem,redisEstimateRSS());
     info = sdscatprintf(sdsempty(),
         "redis_version:%s\r\n"
         "redis_git_sha1:%s\r\n"
@@ -1079,8 +1077,8 @@ sds genRedisInfoString(void) {
         "blocked_clients:%d\r\n"
         "used_memory:%zu\r\n"
         "used_memory_human:%s\r\n"
-        "used_memory_rss:%zu\r\n"
-        "used_memory_estimated_rss:%zu\r\n"
+        "used_memory_zmalloc:%zu\r\n"
+        "used_memory_raw_rss:%zu\r\n"
         "mem_fragmentation_ratio:%.2f\r\n"
         "use_tcmalloc:%d\r\n"
         "changes_since_last_save:%lld\r\n"
@@ -1114,10 +1112,10 @@ sds genRedisInfoString(void) {
         listLength(server.clients)-listLength(server.slaves),
         listLength(server.slaves),
         server.blpop_blocked_clients,
-        zmalloc_used_memory(),
-        hmem,
-        zmalloc_get_rss(),
         redisEstimateRSS(),
+        hmem,
+        zmalloc_used_memory(),
+        zmalloc_get_rss(),
         zmalloc_get_fragmentation_ratio(),
 #ifdef USE_TCMALLOC
         1,
@@ -1285,7 +1283,7 @@ size_t redisEstimateRSS(void) {
 void freeMemoryIfNeeded(void) {
     /* Remove keys accordingly to the active policy as long as we are
      * over the memory limit. */
-    while (server.maxmemory && zmalloc_used_memory() > server.maxmemory) {
+    while (server.maxmemory && redisEstimateRSS() > server.maxmemory) {
         int j, k, freed = 0;
 
         /* Basic strategy -- remove objects from the free list. */