0. 內(nèi)存管理問題
內(nèi)存碎片太小和管理內(nèi)存碎片的效率問題
內(nèi)存碎片:回收內(nèi)存時,將內(nèi)存塊放入free鏈表中。因內(nèi)存越分越小,內(nèi)存塊小而多。當(dāng)需要一塊大內(nèi)存時,盡管此時空閑內(nèi)存的總和可能足夠滿足需求,但是過于零散,沒有一個合適的內(nèi)存塊。
原因:分配內(nèi)存時,不能將相鄰內(nèi)存合并
解決辦法:
- 小塊內(nèi)存單獨分配(內(nèi)存池),大內(nèi)存由操作系統(tǒng)分配。[Nginx,STL采用]
- 伙伴算法
- slab算法
1. 伙伴算法
大致分為以下幾步:
- 將空閑頁面分為m個組。第1組1個塊,第2組2個塊,第三組4個塊,...,第m組2^(m-1)塊
- 每個組是一個鏈表,連接相同大小的塊
- 伙伴塊大小相等
分配內(nèi)存
如果申請的內(nèi)存大小為n,則向上取整為2的冪次數(shù),定位到響應(yīng)組,到組中(鏈表上)找空閑塊分配出去;若沒有空閑塊,則到上一組找,直到找到為止,并將剩余的內(nèi)存放到下面適當(dāng)?shù)慕M中。
合并內(nèi)存
用完內(nèi)存需要歸還,根據(jù)實際內(nèi)存塊大小向上取整為2的冪次數(shù),歸入鏈表。
- 檢測其伙伴塊是否空閑
- 如果空閑就合并在一起,繼續(xù)檢測1
- 如果不空閑,直接歸入鏈表
注:伙伴算法使用位圖標記內(nèi)存塊的使用情況
特點
- 優(yōu)點:解決外部碎片問題,盡量分配連續(xù)的頁面,簡單易行。
- 缺點:容易造成內(nèi)存浪費,比如請求9K的內(nèi)存,卻要到16K的鏈表上找,盡管剩下的7K會下放到后面數(shù)組中,頻繁的合并占用內(nèi)存。可以設(shè)置低潮個數(shù)來解決這個問題。
slab算法
slab以內(nèi)存池為思想,解決內(nèi)部碎片問題,專門解決小內(nèi)存問題。

slab算法