diff --git a/src/config.h b/src/config.h index 6e98fbb2cecbceb32a192f1c8bae367cb1b7a11f..acc95cf52cee467aa8bdeb4123a717f1779356b1 100644 --- a/src/config.h +++ b/src/config.h @@ -21,6 +21,11 @@ #define redis_stat stat #endif +/* test for proc filesystem */ +#ifdef __linux__ +#define HAVE_PROCFS 1 +#endif + /* test for backtrace() */ #if defined(__APPLE__) || defined(__linux__) #define HAVE_BACKTRACE 1 diff --git a/src/redis.c b/src/redis.c index 77e67c5839cfdcea732ef5a42037b75f04f3511a..8206b5d30e561b7087a2e6d2df87f72990b257e9 100644 --- a/src/redis.c +++ b/src/redis.c @@ -1166,6 +1166,7 @@ sds genRedisInfoString(void) { "blocked_clients:%d\r\n" "used_memory:%zu\r\n" "used_memory_human:%s\r\n" + "mem_fragmentation_ratio:%.2f\r\n" "changes_since_last_save:%lld\r\n" "bgsave_in_progress:%d\r\n" "last_save_time:%ld\r\n" @@ -1192,6 +1193,7 @@ sds genRedisInfoString(void) { server.blpop_blocked_clients, zmalloc_used_memory(), hmem, + zmalloc_get_fragmentation_ratio(), server.dirty, server.bgsavechildpid != -1, server.lastsave, diff --git a/src/zmalloc.c b/src/zmalloc.c index 5c1b5e9aaeb86b714000fcf962b311f3dcbb5eec..81fc4c044a68ba4ef425e4fa24703ff8ed20991b 100644 --- a/src/zmalloc.c +++ b/src/zmalloc.c @@ -32,6 +32,10 @@ #include #include #include +#include +#include +#include +#include #include "config.h" #if defined(__sun) @@ -170,3 +174,41 @@ size_t zmalloc_used_memory(void) { void zmalloc_enable_thread_safeness(void) { zmalloc_thread_safe = 1; } + +/* Fragmentation = RSS / allocated-bytes */ +float zmalloc_get_fragmentation_ratio(void) { +#ifdef HAVE_PROCFS + size_t allocated = zmalloc_used_memory(); + int page = sysconf(_SC_PAGESIZE); + size_t rss; + char buf[4096]; + char filename[256]; + int fd, count; + char *p, *x; + + snprintf(filename,256,"/proc/%d/stat",getpid()); + if ((fd = open(filename,O_RDONLY)) == -1) return 0; + if (read(fd,buf,4096) <= 0) { + close(fd); + return 0; + } + close(fd); + + p = buf; + count = 23; /* RSS is the 24th field in /proc//stat */ + while(p && count--) { + p = strchr(p,' '); + if (p) p++; + } + if (!p) return 0; + x = strchr(p,' '); + if (!x) return 0; + *x = '\0'; + + rss = strtoll(p,NULL,10); + rss *= page; + return (float)rss/allocated; +#else + return 0; +#endif +} diff --git a/src/zmalloc.h b/src/zmalloc.h index db858bba0b75ffc50cc206c56c3ecd581e4204a7..281aa3a8b46cde2b6346577a06bb20ecfc965d66 100644 --- a/src/zmalloc.h +++ b/src/zmalloc.h @@ -38,5 +38,6 @@ void zfree(void *ptr); char *zstrdup(const char *s); size_t zmalloc_used_memory(void); void zmalloc_enable_thread_safeness(void); +float zmalloc_get_fragmentation_ratio(void); #endif /* _ZMALLOC_H */