jemalloc在linux的世界里聲名鵲起级乐,并被移植到多個(gè)平臺(tái)议薪。后起之秀的tcmalloc性能與之相近尤蛮,雖有谷歌這個(gè)牛爹,但因jemalloc專美在前斯议,tcmalloc的使用范圍還是略遜一籌产捞。網(wǎng)絡(luò)上關(guān)于jemalloc的各種解讀很多,不再一一贅述哼御,這里 挑一些關(guān)鍵點(diǎn)來(lái)分析坯临。
一、地址訪問(wèn)
malloc和free的第一個(gè)參數(shù)都是內(nèi)存地址恋昼,如何快速定位到該地址所屬的內(nèi)存塊基址呢看靠,在高頻內(nèi)存分配中,這是第一 要?jiǎng)?wù)焰雕。jemalloc使用一個(gè)簡(jiǎn)單的技巧衷笋,chunk = addr & (~chunksize_mask) ,確保尋址O(1)就能完成矩屁。在這個(gè)公式中辟宗,有一個(gè)很隱晦的前提是,chunk的地址吝秕,必須能夠滿足類似0xaabb0000這樣格式泊脐,其尾部0的數(shù)量要大于等于chunksize_mask的F的數(shù)量。
jemalloc在分配時(shí)烁峭,會(huì)做這樣的嘗試容客,alloc_size = size + aligment - PAGE_SIZE,然后去掉頭部约郁,保證chunk地址滿足這樣的條件缩挑。如果不能,則將多余的內(nèi)存地址還給系統(tǒng)鬓梅。
二供置、內(nèi)存頁(yè)管理
小對(duì)象可以用技巧映射到chunk,對(duì)于chunk尋址就沒(méi)有辦法用上面這招了绽快。jemalloc用三層基數(shù)樹(shù)芥丧,所以查找效率還是相當(dāng)高的,只是增刪除改查時(shí)坊罢,需要加鎖续担。加鎖會(huì)影響效率,當(dāng)因?yàn)榇螖?shù)比較少活孩,倒不會(huì)有太大的影響物遇。需要注意的是,jemalloc的這個(gè)全局基數(shù)樹(shù)的節(jié)點(diǎn)在分配之后,是不釋放的挎挖,直到最終進(jìn)程退出这敬。jemalloc從系統(tǒng)中航夺,每次都是以4M為基準(zhǔn)申請(qǐng)的蕉朵。
三、長(zhǎng)度對(duì)齊
在實(shí)際場(chǎng)景中阳掐,請(qǐng)求分配字節(jié)大小是隨機(jī)的始衅,如果按照真實(shí)大小分配,容易引起內(nèi)存頁(yè)缺失中斷缭保,因此需要字節(jié)對(duì)齊汛闸。在jemalloc中,并不是固定字節(jié)對(duì)齊艺骂,而是按照如下的邏輯:
(0)诸老、[0-16] --字節(jié)對(duì)齊-->8
(1)、(16-128] --字節(jié)對(duì)齊-->16
(2)钳恕、(128-256] --字節(jié)對(duì)齊-->32
(3)别伏、(256-512] --字節(jié)對(duì)齊-->64
四、線程競(jìng)爭(zhēng)
在內(nèi)存分配過(guò)程中忧额,鎖會(huì)造成線程等待厘肮,對(duì)性能影響巨大。jemalloc采用了兩種措施避免線程競(jìng)爭(zhēng)鎖的發(fā)生睦番,
1类茂、使用線程變量,每個(gè)線程有自己的內(nèi)存管理器托嚣,分配在這個(gè)線程內(nèi)完成巩检,就不需要和其他線程競(jìng)爭(zhēng)。
2示启、競(jìng)技場(chǎng)兢哭,分配一個(gè)數(shù)組,每個(gè)線程通過(guò)線程號(hào)的映射丑搔,對(duì)應(yīng)到一個(gè)數(shù)組元素中厦瓢。這樣,多個(gè)線程競(jìng)爭(zhēng)一個(gè)元素的概率就下降啤月。
有點(diǎn)令人詫異的是煮仇,jemalloc使用原子操作基本沒(méi)有,鎖都是用粒度較大的mutex谎仲。只有需要較長(zhǎng)等待時(shí)浙垫,比如陷入系統(tǒng)時(shí)才有必要用這種粗粒度的鎖。和競(jìng)技場(chǎng)相關(guān)的資料頗多,可以在網(wǎng)上找找夹姥。
五杉武、分配流程
我們假設(shè)一個(gè)應(yīng)用場(chǎng)景,要分配一個(gè)大小為SIZE的內(nèi)存塊辙售,那么流程如下:
1轻抱、選定一個(gè)arena或者tcache。
2旦部、計(jì)算對(duì)應(yīng)的對(duì)齊長(zhǎng)度祈搜,見(jiàn)第三節(jié),根據(jù)對(duì)齊長(zhǎng)度士八,計(jì)算出arena中bins的下標(biāo)容燕。
3、在一個(gè)bins中婚度,如果runccur可用蘸秘,則在runcur中分配,否則從runs中選擇一個(gè)蝗茁。
4醋虏、從選定的run中,計(jì)算bitmap评甜,得到空閑的region灰粮,后返回。