學(xué)習(xí)redis源碼(1):redis的內(nèi)存管理

? ? ? ?內(nèi)存分配的代碼寫在zmalloc.c和zmalloc.h中尚猿。原理是對(duì)底層內(nèi)存分配方式的再封裝。除此之外楣富,redis沒(méi)有對(duì)內(nèi)存進(jìn)行額外的操作凿掂,因此,內(nèi)存分配器的性能和碎片化率會(huì)對(duì)redis造成一些性能上的影響。其底層內(nèi)存分配會(huì)根據(jù)宏的選擇不同而有所不同庄萎。如果定義了USE_TCMALLOC踪少,則使用tcmalloc;如果定義了USE_JEMALLOC糠涛,則使用jemalloc援奢;否則如果系統(tǒng)自帶c運(yùn)行庫(kù),將會(huì)使用系統(tǒng)自帶的malloc進(jìn)行內(nèi)存分配忍捡;最后才會(huì)使用redis自己的內(nèi)存分配函數(shù)集漾。
redis會(huì)通過(guò)定義宏 HAVE_MALLOC_SIZE為1 來(lái)表示使用的是其他庫(kù)的內(nèi)存分配函數(shù)。
? ? ? ?封裝的底層函數(shù):

malloc_usable_size(p)//返回p對(duì)應(yīng)內(nèi)存的大小
malloc(size)//分配堆內(nèi)存砸脊,內(nèi)容沒(méi)有初始化
calloc(count,size)//在malloc基礎(chǔ)上具篇,將內(nèi)存初始化為0
realloc(ptr,size)
free(ptr)

? ? ? ?對(duì)于特定版本的JEMALLOC,redis實(shí)現(xiàn)了內(nèi)存的碎片化處理凌埂。

? ? ? ?zmalloc里主要的兩個(gè)宏

#define update_zmalloc_stat_alloc(__n) do { \
    size_t _n = (__n); \
    if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \
    atomicIncr(used_memory,__n); \
} while(0)

#define update_zmalloc_stat_free(__n) do { \
    size_t _n = (__n); \
    if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \
    atomicDecr(used_memory,__n); \

? ? ? ?上面兩個(gè)都進(jìn)行了原子操作驱显,保證線程安全;同時(shí)if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)) 確保了64位機(jī)上8字節(jié)對(duì)齊(這個(gè)技巧運(yùn)用了位操作瞳抓,效率很高埃疫;同時(shí)字節(jié)對(duì)齊的單位取決于系統(tǒng),即所謂的軟編碼)孩哑。
? ? ? ?zmalloc里的重要變量:

static size_t used_memory = 0;
pthread_mutex_t used_memory_mutex = PTHREAD_MUTEX_INITIALIZER;
static void (*zmalloc_oom_handler)(size_t) = zmalloc_default_oom;

? ? ? ?zmalloc主要函數(shù)如下:

size_t zmalloc_usable(void *ptr)//返回內(nèi)存大小(不包含prefix的大小)
size_t zmalloc_size(void *ptr)//返回內(nèi)存大小(包含prefix的大小)
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);
size_t zmalloc_used_memory(void);
void zmalloc_set_oom_handler(void (*oom_handler)(size_t));
//獲得系統(tǒng)的配置信息
size_t zmalloc_get_rss(void);//實(shí)際使用的物理內(nèi)存
size_t zmalloc_get_smap_bytes_by_field(char *field, long pid);//得到指定pid指定field對(duì)應(yīng)的值
size_t zmalloc_get_private_dirty(long pid);//上一個(gè)函數(shù)的filed為”Private_Dirty"
int zmalloc_get_allocator_info(size_t *allocated, size_t *active, size_t *resident);//得到已經(jīng)申請(qǐng)了內(nèi)存數(shù)栓霜,活躍的,長(zhǎng)期存在的內(nèi)存數(shù)
size_t zmalloc_get_memory_size(void);//獲得RAM的大小

? ? ? ?redis的內(nèi)存分配方式如下:



? ? ? ?prefix存儲(chǔ)buf的大小臭笆。這種管理方式類似redis中的sds管理方式叙淌。如果使用了外部庫(kù)的內(nèi)存分配函數(shù),PREFIX_SIZE為0愁铺。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鹰霍,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子茵乱,更是在濱河造成了極大的恐慌茂洒,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓶竭,死亡現(xiàn)場(chǎng)離奇詭異督勺,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)斤贰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門智哀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人荧恍,你說(shuō)我怎么就攤上這事瓷叫⊥偷酰” “怎么了?”我有些...
    開封第一講書人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵摹菠,是天一觀的道長(zhǎng)盒卸。 經(jīng)常有香客問(wèn)我,道長(zhǎng)次氨,這世上最難降的妖魔是什么蔽介? 我笑而不...
    開封第一講書人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮煮寡,結(jié)果婚禮上虹蓄,老公的妹妹穿的比我還像新娘。我一直安慰自己洲押,他們只是感情好武花,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著杈帐,像睡著了一般体箕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挑童,一...
    開封第一講書人閱讀 52,255評(píng)論 1 308
  • 那天累铅,我揣著相機(jī)與錄音,去河邊找鬼站叼。 笑死娃兽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的尽楔。 我是一名探鬼主播投储,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼阔馋!你這毒婦竟也來(lái)了玛荞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤呕寝,失蹤者是張志新(化名)和其女友劉穎勋眯,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體下梢,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡客蹋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了孽江。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片讶坯。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖岗屏,靈堂內(nèi)的尸體忽然破棺而出闽巩,到底是詐尸還是另有隱情钧舌,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布涎跨,位于F島的核電站,受9級(jí)特大地震影響崭歧,放射性物質(zhì)發(fā)生泄漏隅很。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一撼泛、第九天 我趴在偏房一處隱蔽的房頂上張望停蕉。 院中可真熱鬧爸吮,春花似錦、人聲如沸绒尊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)婴谱。三九已至,卻和暖如春躯泰,著一層夾襖步出監(jiān)牢的瞬間谭羔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工麦向, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瘟裸,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓诵竭,卻偏偏與公主長(zhǎng)得像话告,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子卵慰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載:可能是目前最詳細(xì)的Redis內(nèi)存模型及應(yīng)用解讀 Redis是目前最火爆的內(nèi)存數(shù)據(jù)庫(kù)之一沙郭,通過(guò)在內(nèi)存中讀寫數(shù)據(jù)...
    meng_philip123閱讀 1,441評(píng)論 1 22
  • 主要函數(shù) void *zmalloc(size_t size); void *zcalloc(size_t siz...
    一只肥豚鼠閱讀 1,156評(píng)論 0 0
  • 轉(zhuǎn)載:可能是目前最詳細(xì)的Redis內(nèi)存模型及應(yīng)用解讀 Redis是目前最火爆的內(nèi)存數(shù)據(jù)庫(kù)之一,通過(guò)在內(nèi)存中讀寫數(shù)據(jù)...
    jwnba24閱讀 624評(píng)論 0 4
  • 前言 Redis是目前最火爆的內(nèi)存數(shù)據(jù)庫(kù)之一呵燕,通過(guò)在內(nèi)存中讀寫數(shù)據(jù)棠绘,大大提高了讀寫速度,可以說(shuō)Redis是實(shí)現(xiàn)網(wǎng)站...
    小陳阿飛閱讀 806評(píng)論 0 1
  • 不識(shí)高頭馬再扭, 未尋萬(wàn)家堂氧苍。 杯中意氣盡, 曲終君王枯泛范。 月未明让虐,風(fēng)卷席。 樽中酒罢荡,慰風(fēng)塵赡突。 殘燈枯等金甌生对扶, 三花...
    惘過(guò)夕川閱讀 378評(píng)論 0 1