伙伴算法 Buddy Algorithm

文章讲述了内存管理中的一种策略,利用free_list数组进行动态内存分配,遵循2的幂次方原则,只向上分配空间,且在释放内存时进行合并操作。每次分配时,根据需要的空间大小向上寻找合适的free_list元素,直到找到足够大的空间或者失败。
摘要由CSDN通过智能技术生成

一块内存区,例如128bytes。

在分配一定大小的连续内存空间k时,例如k=32,那么我们就分配给它32;如果k=31,虽然它小于32,但是它大于16,所以仍然分配32;如果k=33,虽然只比32大1,但终究是大于32而且小于64,所以最终是分配364。总结起来,还是需要符合2的幂次方关系,并且只可向上进,不可向下退。

vector<pair<int, int>> free_list[7];
// 7的来源是2的7次方等于128。

free_list[i]的意义在于,它可以分配连续的2的i次方空间给程序。

将free_list[7]初始化为(0,127),表示自己可以分配自己应该分配的连续空间128bytes

而free_list[0~6]为空,表示无法分配自己应该分配的空间。

当确定最终分配的空间大小alloc_mem时,就选择合适的列表位置,即free_list的第几个元素。

即,将alloc_mem 变为 2^{index},根据Index选择free_list[index]。即,1就找free_list[0],2就找free_list[1],4就找free_list[2],8就找free_list[3],...,128就找free_list[7]。

######################## 分配内存 ########################

开始分配空间,根据32找到free_list[5],

allocate(32);

如果free_list[5]正好有空间,则分配给它就可以。

如果free_list[5]为空,故一直向上寻找空间,直到free_list[n]>0。这时,free_list[n]空间一定大于等于所需空间的2倍,此时将free_list[n]空间分半后给free_list[n-1],free_list[n-1]保留后半部分,free_list[n-1]把前半部分再分半后交给free[n-2],free_list[n-2]保留后半部分,free_list[n-2]把前半部分再分半后交给free[n-3],...,一直到交给free_list[i]后,free_list[i]保留后半部分,free_list[i]把前半部分分配出去给alloc_mem。从n-1到i,他们接收到的空间都是已经分为两半的空间,相同之处都是保留了后半部分空间按,区别在于最后一个i将前半部分分配给alloc_mem了,而n-1他们都是把分配给他们的前半部分再次分半,交给下一个阶段,即n-1分半后给n-2,n-2分半后给n-3,直到i不再将前半部分分半,而是直接分配给alloc_mem,到此,分配结束。

如果free_list[5]为空,并一直向上寻找空间不得,就显示无法分配空间。

第一次分配形象化描述为:

free_list[ ]

初始状态

allocate(32)

0

1

2

3

4

5

[32,63]

6

[64,127]

7

[0,127]

mp

mp[0]=32

map<int, int> mp;
// mp[start]=size,表示内存从start开始的连续size大小空间已经分配

之后继续分配空间

allocate(7);

初始状态

allocate(32)

allocate(7)

0

1

2

3

[40,47]

4

[48,63]

5

[32,63]

6

[64,127]

[64,127]

7

[0,127]

mp

mp[0]=32

mp[0]=32

mp[32]=8

再次分配空间

allocate(2);
allocate(64);
allocate(56);

初始状态

allocate(32)

allocate(7)

allocate(2)

allocate(64)

allocate(56)

0

1

[42,43]

[42,43]

2

[44,47]

[44,47]

3

[40,47]

4

[48,63]

[48,63]

[48,63]

5

[32,63]

6

[64,127]

[64,127]

[64,127]

7

[0,127]

failed

mp

mp[0]=32

mp[0]=32

mp[32]=8

mp[0]=32

mp[32]=8

mp[40]=2

mp[0]=32

mp[32]=8

mp[40]=2

mp[64]=64

规律:首先根据alloc_mem= 2^{index}找到index,例如allocate(7)时,index就等于3。然后在之前allocate(32)的基础上,就一直向上找第一个不为空的free_list[i],此时i=5,然后把free_list[[5]减半给下一个,一直重复到我们的index=3,然后free_list[3]就保留后半部分空间,前半部分分配出去就行了。如果一直向上找都为空,即分配allocate(56)时,自己的index=6,但是向上找都是空,那么就分配失败。

######################## 释放内存 ########################

当一个进程结束时,就把他的空间释放掉,根据mp[start]=size可以轻松释放占用的内存。

下一步就是合并空闲内存。即自己释放的内存一定是2的i次方,那么,free_list[i]它也可以分配空间,两者的空间大小一样,那么如果释放的内存和free_list[i]可以分配的内存是连续的空间,就可以合并起来,把内存变大两倍,free_list[i]就晋级为free_list[i+1]了。再进一步,如果free_list[i+1]也有内存可以分配,并且和我们的连续,就再来一次合并,一直到不可以为止。

  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jsj小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值