【操作系统】实验:内存管理

目录

一、实验目的

二、实验要求

三、实验步骤

四、核心代码

五、记录与处理

六、思考

七、完整报告和成果文件提取链接


一、实验目的

1、加深对固定和动态分区分配内存管理方式的理解

2、理解动态分区分配算法:首次适应算法,循环首次适应算法,最佳适应算法

二、实验要求

先选择内存分配策略,根据进程申请的空间大小,查找分区说明表根据内存分配策略申请分区表。当进程结束时,修改对应的分区表,回收内存空间,从而完成内存的申请和释放。

三、实验步骤

固定方式:

1. 初始状态内存含有 5 块分区块(可以是大小相等,也可以大小不等),分区说明表记录内存使用信息;

2. 设置多个进程(包含申请的内存大小信息)放入后备队列,进程申请空间,操作系统根据申请空间大小,查找分区说明表,找是否有合适的空间,如果找到,将内存分给进程;否则,继续等待;

3. 根据进程的退出次序,再将空间依次进行回收,修改分区说明表,当有一空闲分区时,便可以再从后备作业队列中,选择一个适当大小的作业装入该分区,并修改分区说明表;

4. 要求当每次修改分区说明表时,都要打印一次分区说明表的信息,以及进程信息。

动态方式:

1. 初始状态内存含有1块空闲分区块,空闲分区说明表记录内存信息,已占分区表为空;

2. 选择内存分配策略,创建多个进程(包含申请的内存大小信息),这多个进程依次申请空间,操作系统采用选取的内存分配策略将内存分给每个进程,并修改空闲分区说明表和已占分区说明表;

3. 通过控制台来退出一些进程,再将空间依次进行回收,修改空闲分区说明表和已占分区说明表;

4. 要求当每次修改分区说明表时,都要打印一次分区说明表的信息,以及进程信息。

四、核心代码

void Creat_list(PNode list)
{
	assert(NULL != list);
	int _id = -1, _num = 0;
	long _size = -1;
	long _locat = list->start_locat;
	cout << "请输入申请资源的进程个数:" << endl;
	cin >> _num;
	for (int i = 0; i <= _num; i++)
	{
		Node* newnode = (Node*)malloc(sizeof(Node));
		assert(NULL != newnode);
		if (i < _num)
		{
           cout << "请输入第" << i + 1 << "个进程调入的分区号及其大小:" << endl;
		   cin >> _id >> _size;
		   newnode->pid = _id;
		   newnode->size = _size;
		   newnode->start_locat = _locat;
		   newnode->status = 1;
		   _locat += _size;
		}
		else
		{
			newnode->pid = -1;
			newnode->size = memory_size - _locat;
			newnode->start_locat = _locat;
			newnode->status = 0;
			free_num++;
		}
		PNode ptr = list;
		for (ptr; ptr->next != list; ptr = ptr->next);
		newnode->next = list;
		newnode->perior = ptr;
		ptr->next = newnode;
		list->perior = newnode;
	}
}
PNode Insert_Node()
{
	Node* newnode = (Node*)malloc(sizeof(Node));
	assert(NULL != newnode);
	int _id = 0;
	long _size = 0;
	cout << "请输入进程调入的分区号及其大小:" << endl;
	cin >> _id >> _size;
	newnode->next = NULL;
	newnode->perior = NULL;
	newnode->pid = _id;
	newnode->size = _size;
	newnode->start_locat = 0;
	newnode->status = 0;
	return newnode;

}
void First_fit(PNode list)
{
	assert(NULL != list);
	PNode _head = Insert_Node();
	PNode ptr = list;
	while (ptr->next != list)
	{
		PNode cur = ptr->next;
		if (cur->status==0&&cur->size > _head->size)
		{ 
			_head->next = cur;
			_head->perior = ptr;
             cur->perior = _head;
			 ptr->next = _head;
			_head->status = 1;
			_head->start_locat = ptr->start_locat + ptr->size;
			cur->start_locat = _head->start_locat + _head->size;
			cur->size = cur->size - _head->size;
			break;
		}
		else if (cur->status == 0&&cur->size == _head->size)
		{
			cur->pid = _head->pid;
			cur->status = 1;
			free_num--;
			break;
		}
		ptr = ptr->next;
	}
	if (ptr->next->status == 0)
	{
		cout << "没有适合的申请位置" << endl;
	}
}
void Next_fit(PNode list)
{
	assert(NULL != list);
	PNode _head = Insert_Node();
	PNode p = list;
	if (Flag_Node != NULL)
	{
		p = Flag_Node;
	}
	PNode ptr = p;
	while (ptr->next != p)
	{
		PNode cur = ptr->next;
		if (cur->status == 0 && cur->size > _head->size)
		{
			_head->next = cur;
			_head->perior = ptr;
			cur->perior = _head;
			ptr->next = _head;
			_head->status = 1;
			_head->start_locat = ptr->start_locat + ptr->size;
			cur->start_locat = _head->start_locat + _head->size;
			cur->size = cur->size - _head->size;
			Flag_Node = _head;
			break;
		}
		else if (cur->status == 0 && cur->size == _head->size)
		{
			cur->pid = _head->pid;
			cur->status = 1;
			Flag_Node = cur;
			free_num--;
			break;
		}
		ptr = ptr->next;
	}
	if (ptr->next->status == 0)
	{
		cout << "没有适合的申请位置" << endl;
	}
}
long* _Sort_min(long* p)
{
	assert(NULL != p);
	for (int i = 0; i < free_num-1; i++)
	{
		for (int j = 0; j < free_num - 1 - i; j++)
		{
			if (p[j] > p[j + 1])
			{
				long tmp = p[j];
				p[j] = p[j + 1];
				p[j + 1] = tmp;
			}
		}
	 }
	return p;
}
void Best_fit(PNode list)
{
	assert(NULL != list);
	PNode _head = Insert_Node();
	long* p = (long*)malloc(sizeof(long)*(free_num));
	assert(NULL!=p);
	PNode ptr = list->next;
	long i = 0, j = 0;
	while (ptr!= list)
	{
		if (ptr->status == 0)
		{
			*(p+i) = ptr->size;
			i++;
		}
		ptr = ptr->next;
	}
	long* q = _Sort_min(p);
	while (j < free_num)
	{
		if (_head->size < q[j])
		{
			break;
		}
		j++;
	}
	PNode cur = list;
	while (cur->next != list)
	{
		PNode tr = cur->next;
		if (tr->status==0&&tr->size == q[j])
		{
			if (_head->size < tr->size)
			{
				_head->next = tr;
				_head->perior = cur;
				tr->perior = _head;
				cur->next = _head;
				_head->status = 1;
				_head->start_locat = cur->start_locat + cur->size;
				tr->start_locat = _head->start_locat + _head->size;
				tr->size = tr->size - _head->size;
				break;
			}
			else if(_head->size==tr->size)
			{
				tr->pid = _head->pid;
				tr->status = 1;
				break;
			}
		}
		cur = cur->next;
	}
}

五、记录与处理

运行结果如下:

1.首先以地址为0内存大小为1024,对链表进行初始化,输入申请资源的三个进程的分区号以及大小。

2.然后选用首次适应算法申请分区号为4大小为428的进程。

3.然后进行回收进程号算法 第二第四未被回收

4. 使用循环适应算法 申请12分区号大小为26的分区

5. 使用最佳适应算法 申请13分区号大小为30的分区

六、思考

简述固定分区和动态分区两种连续分配存储管理方式的优缺点?

固定分区和动态分区两种连续分配存储管理方式各有其优缺点。具体来说:

固定分区优点:

1.数据访问速度快:由于数据和指令在内存中是连续存放的,访问速度较快。

2.空间利用率高:可以根据进程的大小动态分配内存空间,避免了浪费。

3.管理简单:不需要复杂的算法和数据结构,内存管理的开销较小。

固定分区缺点:

1.系统开销大:需要维护大量的分区表等数据结构,增加了系统的开销。

2.内存碎片多:随着时间的推移,可能会出现大量的内存碎片,影响内存的利用率。

3.无法充分利用内存资源:由于每个进程都分配一个或多个连续的分区,即使某些分区的大小不足以容纳一个完整的程序,也无法将其用于其他程序的运行,导致内存资源的浪费。

4.不支持多道程序设计技术:不允许多个程序同时驻留在内存中,从而无法充分利用内存资源。

动态分区优点:

1.更高的灵活性:分区的大小和位置可以根据需要进行动态调整,提供了更高的灵活性。

2.更高效的空间利用:可以根据程序的实际大小动态分配内存,从而更有效地利用内存空间。

3.适合多道程序系统:能够更好地支持多道程序并发执行,提高了系统的并发性能。

动态分区缺点:

1.管理复杂性:动态分区需要更多的数据结构和算法来管理内存,增加了系统的复杂性。

2.分配过程较慢:因为需要在运行时查找合适的空闲分区,这会增加内存分配的时间开销。

3.可能产生外部碎片:频繁的分配和释放操作可能导致大量外部碎片的产生,影响内存的长期使用效率。

总的来说,固定分区方式在管理上较为简单,适合对稳定性要求较高的系统,但在空间利用和灵活性方面存在不足;而动态分区方式虽然在管理上更为复杂,却能提供更高的空间利用率和灵活性,更适合现代操作系统的需求。在实际应用中,选择合适的存储管理方式需要根据系统的具体要求和运行环境来决定。

七、完整报告和成果文件提取链接

链接:https://pan.baidu.com/s/1UbP6729pCluscVW0_9oI8w?pwd=1xki 
提取码:1xki 

  • 21
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值