本篇內容主要講解“redis在內存分配和使用統計的技巧有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Redis在內存分配和使用統計的技巧有哪些”吧!
成都創新互聯公司擁有一支富有激情的企業網站制作團隊,在互聯網網站建設行業深耕10余年,專業且經驗豐富。10余年網站優化營銷經驗,我們已為上1000+中小企業提供了網站建設、網站設計解決方案,按需設計網站,設計滿意,售后服務無憂。所有客戶皆提供一年免費網站維護!
具體來說就是:
若系統中存在Google的TC_MALLOC庫,則使用tc_malloc一族函數代替原本的malloc一族函數。
若當前系統是Mac系統,則使用中的內存分配函數。
其他情況,在每一段分配好的空間前頭,同時多分配一個定長的字段,用來記錄分配的空間大小。
源代碼分別在 config.h 和 zmalloc.c 中:
/* config.h */
#if defined(USE_TCMALLOC)
#include
#if TC_VERSION_MAJOR >= 1 && TC_VERSION_MINOR >= 6
#define HAVE_MALLOC_SIZE 1
#define redis_malloc_size(p) tc_malloc_size(p)
#endif
#elif defined(__APPLE__)
#include
#define HAVE_MALLOC_SIZE 1
#define redis_malloc_size(p) malloc_size(p)
#endif
/* zmalloc.c */
#ifdef HAVE_MALLOC_SIZE
#define PREFIX_SIZE (0)
#else
#if defined(__sun)
#define PREFIX_SIZE (sizeof(long long))
#else
#define PREFIX_SIZE (sizeof(size_t))
#endif
#endif
因為 tc_malloc 和 Mac平臺下的 malloc 函數族提供了計算已分配空間大小的函數(分別是tc_malloc_size和malloc_size),所以就不需要單獨分配一段空間記錄大小了。而針對linux和sun平臺則要記錄分配空間大小。對于linux,使用sizeof(size_t)定長字段記錄;對于sun os,使用sizeof(long long)定長字段記錄。也就是上邊源碼中的 PREFIX_SIZE 宏。
那么這個記錄有什么用呢?答案是,為了統計當前進程到底占用了多少內存。在 zmalloc.c 中,有這樣一個靜態變量:
static size_t used_memory = 0;
它記錄了進程當前占用的內存總數。每當要分配內存或是釋放內存的時候,都要更新這個變量。因為分配內存的時候,可以明確知道要分配多少內存。但是釋放內存的時候,(對于未提供malloc_size函數的平臺)僅通過指向要釋放內存的指針是不能知道釋放的空間到底有多大的。這個時候,上邊提到的PREFIX_SIZE定長字段就起作用了,可以通過其中記錄的內容得到空間的大小。zmalloc函數如下(去掉無關代碼):
void *zmalloc(size_t size) {
void *ptr = malloc(size+PREFIX_SIZE);
if (!ptr) zmalloc_oom(size);
*((size_t*)ptr) = size;
update_zmalloc_stat_alloc(size+PREFIX_SIZE,size);
return (char*)ptr+PREFIX_SIZE;
#endif
}
Redis在內存分配和使用統計方面有哪些技巧
看到在分配空間的時候,空間大小是size+PREFIX_SIZE。對于mac系統或是使用tc_malloc的情況,PREFIX_SIZE 為0。之后將ptr指針指向的空間前size_t中記錄分配空間的大小。最后返回的是越過記錄區的指針。zfree函數類似(去掉無關代碼):
void zfree(void *ptr) {
void *realptr;
size_t oldsize;
if (ptr == NULL) return;
realptr = (char*)ptr-PREFIX_SIZE;
oldsize = *((size_t*)realptr);
update_zmalloc_stat_free(oldsize+PREFIX_SIZE);
free(realptr);
#endif
}
先將指針向前移動PREFIX_SIZE,然后取出分配空間時保存的空間長度。最后free整個空間。
update_zmalloc_stat_alloc(__n,__size) 和 update_zmalloc_stat_free(__n) 這兩個宏負責在分配內存或是釋放內存的時候更新used_memory變量。定義成宏主要是出于效率上的考慮。將其還原為函數,就是下邊這個樣子:
void update_zmalloc_stat_alloc(__n,__size)
{
do {
size_t _n = (__n);
size_t _stat_slot = (__size < ZMALLOC_MAX_ALLOC_STAT) ? __size : ZMALLOC_MAX_ALLOC_STAT; 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; zmalloc_allocations[_stat_slot]++; pthread_mutex_unlock(&used_memory_mutex); } else { used_memory += _n; zmalloc_allocations[_stat_slot]++; } } while(0) } void 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變量外,還有幾個要關注的地方: 先對_n的低位向上取整,最后_n變為sizeof(long)的倍數,比如對于32位系統,sizeof(long) == 100(二進制),_n向上取整之后,低兩位都變為0。 如果進程中有多個線程存在,則在更新變量的時候要加鎖。 在zmalloc函數中還有一個統計量要更新:zmalloc_allocations[]。 在 zmalloc.c 中,zmalloc_allocations是這樣定義的: size_t zmalloc_allocations[ZMALLOC_MAX_ALLOC_STAT+1]; 其作用是統計程序分配內存時,對不同大小空間的請求次數。統計的空間范圍從1字節到256字節,大于256字節的算為256。統計結果通過調用 zmalloc_allocations_for_size 函數返回: size_t zmalloc_allocations_for_size(size_t size) { if (size > ZMALLOC_MAX_ALLOC_STAT) return 0;
return zmalloc_allocations[size];
}
另一個對內存使用量的統計通過調用 zmalloc_used_memory 函數返回:
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.c 中,還針對不同的系統實現了 zmalloc_get_rss 函數,在linux系統中是通過讀取/proc/$pid/stat文件獲得系統統計的內存占用量。
到此,相信大家對“Redis在內存分配和使用統計的技巧有哪些”有了更深的了解,不妨來實際操作一番吧!這里是創新互聯網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
標題名稱:Redis在內存分配和使用統計的技巧有哪些
網頁網址:http://vcdvsql.cn/article8/pepsip.html
成都網站建設公司_創新互聯,為您提供用戶體驗、網站導航、關鍵詞優化、網站制作、服務器托管、定制開發
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯