0. 內(nèi)存管理問(wèn)題
內(nèi)存碎片太小和管理內(nèi)存碎片的效率問(wèn)題
內(nèi)存碎片:回收內(nèi)存時(shí),將內(nèi)存塊放入free鏈表中妄迁。因內(nèi)存越分越小卵渴,內(nèi)存塊小而多瓣赂。當(dāng)需要一塊大內(nèi)存時(shí),盡管此時(shí)空閑內(nèi)存的總和可能足夠滿(mǎn)足需求片拍,但是過(guò)于零散煌集,沒(méi)有一個(gè)合適的內(nèi)存塊。
原因:分配內(nèi)存時(shí)捌省,不能將相鄰內(nèi)存合并
解決辦法:
- 小塊內(nèi)存單獨(dú)分配(內(nèi)存池)苫纤,大內(nèi)存由操作系統(tǒng)分配。[Nginx纲缓,STL采用]
- 伙伴算法
- slab算法
1. 伙伴算法
大致分為以下幾步:
- 將空閑頁(yè)面分為m個(gè)組卷拘。第1組1個(gè)塊,第2組2個(gè)塊祝高,第三組4個(gè)塊栗弟,...,第m組2^(m-1)塊
- 每個(gè)組是一個(gè)鏈表工闺,連接相同大小的塊
- 伙伴塊大小相等
分配內(nèi)存
如果申請(qǐng)的內(nèi)存大小為n乍赫,則向上取整為2的冪次數(shù),定位到響應(yīng)組斤寂,到組中(鏈表上)找空閑塊分配出去耿焊;若沒(méi)有空閑塊,則到上一組找遍搞,直到找到為止罗侯,并將剩余的內(nèi)存放到下面適當(dāng)?shù)慕M中。
合并內(nèi)存
用完內(nèi)存需要?dú)w還溪猿,根據(jù)實(shí)際內(nèi)存塊大小向上取整為2的冪次數(shù)钩杰,歸入鏈表。
- 檢測(cè)其伙伴塊是否空閑
- 如果空閑就合并在一起诊县,繼續(xù)檢測(cè)1
- 如果不空閑讲弄,直接歸入鏈表
注:伙伴算法使用位圖標(biāo)記內(nèi)存塊的使用情況
特點(diǎn)
- 優(yōu)點(diǎn):解決外部碎片問(wèn)題,盡量分配連續(xù)的頁(yè)面依痊,簡(jiǎn)單易行避除。
- 缺點(diǎn):容易造成內(nèi)存浪費(fèi),比如請(qǐng)求9K的內(nèi)存胸嘁,卻要到16K的鏈表上找瓶摆,盡管剩下的7K會(huì)下放到后面數(shù)組中,頻繁的合并占用內(nèi)存性宏∪壕可以設(shè)置低潮個(gè)數(shù)來(lái)解決這個(gè)問(wèn)題。
slab算法
slab以?xún)?nèi)存池為思想毫胜,解決內(nèi)部碎片問(wèn)題书斜,專(zhuān)門(mén)解決小內(nèi)存問(wèn)題诬辈。