我再也不會相信國產帖子的質量了,以后凡是遇到操作系統,內核,高深算法,通通谷歌去。伙伴算法百度了半天,一篇深入淺出的都沒有,隨便谷歌了一下,外文一篇簡單的帖子質量好得尖叫。
buddy system簡介:
buddy system內存管理,努力讓內存分配與相鄰內存合並能快速進行(對於普通算法來講,合並內存相當困難),它利用的是計算機擅長處理2的冪運算。
我們創建一系列空閑塊列表,每一種都是2的倍數。
舉個例子,如果最小分配單元是8字節,整個內存空間有1M。我們創建8字節內存塊鏈表,16字節內存塊鏈表,32字節內存塊鏈表,64,128,256,512,1k,2K, 4K, 8K, 16K, 32K, 64K, 128K, 256K, 512K 和一個1M內存塊鏈表。
除了1M內存塊鏈表有一個可用單元,其余鏈表初始為空。所有的內存分配都會向上取整到2的倍數----70K會向上取整到128K,15K會向上取整到16K,等等。
什么是Buddy
buddy system允許一個被分配塊單元平均拆分成兩個大小是原來一半的塊單元,這兩個塊單元互為伙伴。塊B的伙伴必須滿足大小跟塊B一樣大,並且內存地址相鄰(才可以合並)。
另一個伙伴性質是所有塊單元在內存中的地址必須能被它自己的大小整除。比如16字節的塊的地址都是一些16的倍數,如64字節的塊的地址都是一些64的倍數,等等。
不僅如此,低地址的“伙伴”必須在一個能它“父親塊大小”整除,簡單的說,來自同一個大塊的兩個小塊才是伙伴。
分配內存示例
我們想分配70K的塊空間
1.70K向上取整到2的倍數:128K
2.查詢有128K空閑塊嗎?
3.沒有,分配256K塊。
a.有256K的空閑塊嗎?
b.沒有,分配512K的塊。
i.有512K空閑塊嗎?
ii.沒有,分配1M的空閑塊
i.有1M的空閑塊嗎?
ii.有,從1M的那個空閑鏈表中摘下,分配出去
iii.拆開一半掛在512k空閑鏈表上
iv.返回另一半512K塊
c.拆開一半掛在256k空閑鏈表上
d.返回另一半256k塊
4.將獲得的256K的塊拆兩半,一半掛在128K空閑鏈表中
5.另一半128K塊返回用戶。
內存回收示例
當回收一個內存塊,我們把它掛到對應的空閑鏈表上,然后查詢它的伙伴是不是也在這個空閑鏈表上,如果是則合並他們然后掛接在對應2倍大小塊所對應的空閑鏈表。重復該邏輯。假設我們回收剛剛分配的128K塊內存
1.這個128K的塊的伙伴也在128K的空閑鏈表上嗎?
2.是的,移除它的128K伙伴塊。
3.合並成256K的內存塊
a.這個256K的塊的伙伴也在256K空閑鏈表上嗎?
b.是的,移除該伙伴並合並成512K的塊。
c.這個512K的塊的伙伴也在512K空閑鏈表上嗎?
d.是的,移除該伙伴並合並成1M的塊。
e.這個1M的塊的伙伴也在1M空閑鏈表上嗎?
f.沒有,添加這個1M的塊在1M的空閑鏈表上。
算法的優劣勢分析
buddy system能很快地分配和回收內存塊,但有內碎片,因為它要向上取2的冪的塊大小,有空間浪費,但這是所有內存分配算法都避免不了的。linux系統使用它來分配內存頁,很可能是因為內存頁的大小是2的次冪。
update:2016-1-29
buddy算法屬於內核內存的分配,而非用戶進程內存的分配。