算法原理:
- 首次适应算法 :该算法从空闲分区链首开始查找,直至找到一个能满足其大小要求的空闲分区为止。然后再按照作业的大小,从该分区中划出一块内存分配给请求者,余下的空闲分区仍留在空闲分区链中。
- 内存回收: 主要在广义上介绍回收方法,而不拘泥于细节。随着系统的运行,内存会逐渐被消耗,而内存主要占用的部分有两个,分别是高速缓存以及用户进程,内核高速缓存包括磁盘高速缓存,slab缓存等。
算法实现序列
假设初始状态下可用的内存空间为640KB,并有下列请求序列:
实验进程 |
---|
作业1申请130KB。 |
作业2申请60KB。 |
作业3申请100KB。 |
作业2释放60KB。 |
作业4申请200KB。 |
作业3释放100KB。 |
作业1释放130KB |
作业5申请140KB。 |
作业6申请60KB。 |
作业7申请50KB |
作业6释放60KB。 |
实现代码:
class Block:
def __init__(self, sid, start, size, status, jobname):
self.sid = sid
# 分区号sid
self.start = start
# 分区起始地址start
self.size = size
# 分区大小size
self.status = status
# 分区状态status,e-空闲,1-已分配
self.jobname = jobname # 进程名jobname,使用分区的进程名(作业名)
BlockList = [] # 分区表
block_num = 0 # 分区号,初始为e,分区分配则增加1,回收分区则减1
# 分区分配jobname-作业名,jobsize-作业大小
def allocation(jobname, jobsize):
for b in BlockList:
# 空闲分区大小与作业大小相等,直接修改分区状态为1,作业名设置为jobname的值
if b.size == jobsize and b.status == 0:
b.status = 1
b.jobname = jobname
break
# 空闲分区大小大于作业大小,当前空闲分区分割成2部分:前半部分为被作业占有的分区,后半部分为剩余空闲分区
if b.size > jobsize and b.status == 0:
pos = BlockList.index(b) # 获取当前空闲分区在分区表里的位置
global block_num
block_num = block_num + 1 # 分区号增加
b1 = Block(block_num, b.start + jobsize, b.size - jobsize, 0, ' ') # 分割后的剩余空闲分区"
BlockList.insert(pos + 1, b1) # 剩余空闲分区插入到分区表中,即原分区后增加
b.status = 1 # 当前分区状态设置为1
b.size = jobsize # 当前分区大小设置为作业大小
b.jobname = jobname # 当前分区的作业名设置为jobname
break
BlockList.sort(key=lambda b: b.start) # 按分区起始地址排序
# 回收分区
def recycle(sid):
# 明确回收分区在分区表中的位置pos
pos = -1
flag = False # 前无空闲后无空闲标记
for b in BlockList:
if b.sid == sid:
pos = BlockList.index(b)
if pos < 0:
print('无此分区')
return
#
b1 = BlockList[pos] # 获取回收分区的分区信息#不是第一分区且前一分区为空闲分区
if pos > 0 and BlockList[pos - 1].status == 0:
BlockList[pos - 1].size += b1.size # 前一空闲分区大小增加回收分区的大小
flag = True # 改变标记,表明此时回收分区已和前一空闲分区合并,也可以表明该回收分区前有空闲#不是最后分区且后一分区为空闲分区
if pos < len(BlockList) - 1 and BlockList[pos + 1].status == 0:
if flag is True: # 回收分区已和前一空闲分区合并的情况,需判断其后一分区是否空闲
BlockList[pos - 1].size += BlockList[pos + 1].size # 将回收分区的后空闲分区合并到回收分区的前空闲分区
BlockList.remove(BlockList[pos + 1]) # 移除回收分区的后空闲分区,因为已被合并
else: # 回收分区未和前一空闲分区合并的情况,需判断其后一分区是否空闲
BlockList[pos + 1].size += b1.size # 后一空闲分区大小增加回收分区的大小
BlockList[pos + 1].start = b1.start # 后一空闲分区起始地址设为回收分区的起始地址
flag = True # 改变标记,表明此时回收分区己和后一空闲分区合并,也可以表明该回收分区后有空闲
if not flag: # 前无空闲后无空闲
b1.status = 0 # 直接修改空闲区状态
b1.jobname = ' ' # 清空进程名
return
BlockList.remove(b1) # 移除回收分区
# 输出信息
def printinfo():
s = "{0:7}{1:7}{2:7}{3:7}{4:7}".format('分区号', '起始地址', '分区大小', '分区状态', '占有分区的作业名')
print(s)
for b in BlockList:
if b.jobname == '':
j = '/ '
else:
j = b.jobname
if b.status == 0:
s = "{0:^10}{1:^10}{2:^10}{3:^10}{4:^10}".format(b.sid, b.start, b.size, '空闲', j)
print(s)
if b.status == 1:
s = "{0:^10}{1:^10}{2:^10}{3:^10}{4:^10}".format(b.sid, b.start, b.size, '已分配', j)
print(s)
if __name__ == '__main__':
b = Block(block_num, 0, 640, 0, '') # 初始空闲分区640
BlockList.append(b)
print('初始空间情况')
printinfo()
print('---------------------------------------------------------')
allocation('J1', 130)
allocation('J2', 60)
allocation('J3', 100)
print('J1-J3三个作业的分区分配情况(J1-130KB,J2-60KB,J3-100KB)')
printinfo()
print('---------------------------------------------------------')
recycle(1)
print('回收分区1')
printinfo()
print('---------------------------------------------------------')
allocation('J4', 200)
print('作业J4分区分配情况(J4-200KB)')
printinfo()
print('---------------------------------------------------------')
recycle(2)
print('回收分区2')
printinfo()
print('---------------------------------------------------------')
recycle(0)
print('回收分区0')
printinfo()
print('---------------------------------------------------------')
allocation('J5', 140)
print('作业J5分区分配情况(J5-140KB)')
printinfo()
# print('---------------------------------------------------------')
# recycle(3)
# print('回收分区3')
# printinfo()
print('---------------------------------------------------------')
allocation('J6', 60)
print('作业J6分区分配情况(J6-60KB)')
printinfo()
print('---------------------------------------------------------')
allocation('J7', 50)
print('作业J7分区分配情况(J7-50KB)')
printinfo()
print('---------------------------------------------------------')
recycle(5)
print('回收分区5')
printinfo()
print('---------------------------------------------------------')
实现结果:
转载此博客请注明来源,谢谢