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

news2024/9/23 5:29:14

目录

一、实验目的

二、实验要求

三、实验步骤

四、核心代码

五、记录与处理

六、思考

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


一、实验目的

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 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2078598.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文心一言 VS 讯飞星火 VS chatgpt (334)-- 算法导论23.1 3题

三、证明&#xff1a;如果图G的一条边(u&#xff0c;v)包含在图G的某棵最小生成树中&#xff0c;则该条边是横跨图G的某个切割的一条轻量级边。 文心一言&#xff1a; 为了证明这个命题&#xff0c;我们可以按照以下步骤进行&#xff1a; 第一步&#xff0c;假设图 G G G的一…

程序员对未来思考:面向AI编程;继2B,2C后,2AI开发工程师能否成为未来?

目录 前言当前AI状况幻觉问题上下文长度限制人在回路、提示工程师 AI对未来的影响AI改变了交互形式穿孔纸带命令行时代图形用户界面对话式交互 AI无法直接影响物理世界AI 与开发者AI2B\2C\2G\2AI2AI、AI的幻想 前言 在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&a…

【三指针法】颜色分类

目录 1.前言2.题目简介3.求解思路4.示例代码 1.前言 2.题目简介 题目链接&#xff1a;LINK 3.求解思路 求解思路&#xff1a;三指针法 4.示例代码 class Solution { public:void sortColors(vector<int>& nums) {int i 0;int left -1;int right nums.size…

JAVA安全之Velocity模板注入刨析

文章前言 关于Velocity模板注入注入之前一直缺乏一个系统性的学习和整理&#xff0c;搜索网上大多数类似的内容都是一些关于漏洞利用的复现&#xff0c;而且大多都仅限于Velocity.evaluate的执行&#xff0c;对于载荷的构造以及执行过程并没有详细的流程分析&#xff0c;于是乎…

大模型学习必备指南:深入解析技术原理与应用,从入门到精通一应俱全

目录 1. 深度神经网络 2. 激活函数 3. 损失函数 4. 优化算法 5. 正则化 6. 模型结构 7. 预训练与微调 8. 模型压缩与加速 9. 解释性与可解释性 10. 隐私与安全 11. 总结 推荐阅读 有人说&#xff0c;最近我们都患上了大模型焦虑症。 随着计算能力的提升和数据量的…

视频MOV如何转换成MP4?介绍这些转换方案

视频MOV如何转换成MP4&#xff1f;不同的应用场景往往需要使用不同格式的视频文件,其中MOV 和 MP4 是两种常见的视频格式。MOV 格式由苹果公司开发&#xff0c;主要用于 QuickTime 平台&#xff1b;而 MP4 格式则是一种更为通用的标准&#xff0c;广泛应用于互联网、移动设备以…

Java 输入与输出之 NIO【非阻塞式IO】【NIO核心原理】探索之【一】

Java标准的输入/输出&#xff08;Input/Output&#xff0c;简称I/O&#xff09;是Java程序与外部世界进行交互的重要机制&#xff0c;它允许程序读取和写入数据到各种类型的源&#xff0c;如文件、网络套接字、管道、内存缓冲区等。Java I/O API主要位于java.io包中&#xff0c…

SqlHelper 使用EF-Core框架 连接池处理并发

定义数据库 数据库名称&#xff1a;T_dicomPatientMsg 注意5大约束条件&#xff1a; 1.主键约束&#xff1a;primary key IDKEY设置为主键&#xff0c;主键设置自增长 2.唯一性约束&#xff1a;unique 3.默认约束&#xff1a;default 所有值都要设置默认值&#xff0c…

Unraid 手动安装docker

目录 常用镜像链接一.安装示例1[firefox浏览器]:1.离线下载docker镜像2.将xxx.tar镜像数据加载到 Docker 中3.手动添加docker 二.安装示例2[等我有东西需要安装再回来补教程吧]:三.获取UDI和GID 常用镜像链接 特别版 emby 文件管理器 filebrowser内外穿透 zerotierNAS媒体库管…

Python和Pycharm安装

有需要的私聊我吧&#xff01;&#xff01;&#xff01;

伺服电机最佳速度范围是多少?

伺服电机的最佳速度范围取决于多种因素&#xff0c;包括电机的规格、负载类型、控制要求和应用环境等。一般来说&#xff0c;伺服电机的最佳速度范围是其额定转速的70%到100%之间。这一范围内&#xff0c;电机能够提供最佳的效率、精度和响应速度。 关键因素影响伺服电机速度范…

从B端工程师到AI绘画工程师:我的转行之路与实战指南

一、背景&#xff1a;B端工程师的迷茫与探索 大家好&#xff0c;我是一名有着五年B端服务经验的软件工程师。在长期的B端工作中&#xff0c;我逐渐感到自己的技术栈和视野受限&#xff0c;对未来的职业发展产生了迷茫。在一次偶然的机会中&#xff0c;我接触到了AI绘画这一领域…

nacos 安装

1. 环境准备 使用此快速开始方法进行Nacos安装及部署&#xff0c;需要安装Docker和Docker Compose。 如何下载不下来&#xff0c;可换镜像加速地址 vi /etc/docker/daemon.json {"registry-mirrors": ["https://docker.registry.cyou"] }可用镜像加速地…

合宙Air700EAQ硬件设计手册——应用接口2

Air700EAQ是一款基于移芯EC716E平台设计的LTE Cat 1无线通信模组。 支持亚洲FDD-LTE的4G远距离无线传 输技术。 以极小封装&#xff0c;极高性价比&#xff0c;满足IoT行业的数传应用需求。 例如共享应用场景&#xff0c;定位器场景&#xff0c;DTU数 传场景等。 在上文我们…

E82EV752K4C变频器可议价

E82EV752K4C变频器可议价 E82EV752K4C变频器可议价 E82EV752K4C变频器可议价 E82EV752K4C变频器参数表 E82EV752K4C变频器引脚图 E82EV752K4C变频器线路图 E82EV752K4C变频器节能主要表现在风机、水泵的应用上。风机、泵类负载采用变频调速后&#xff0c;节电率为20%&…

基于Java+SpringBoot+Vue的知识管理系统

基于JavaSpringBootVue的知识管理系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 哈喽…

AI驱动的Web3革命:如何通过智能技术实现去中心化

在当今的数字世界中&#xff0c;人工智能&#xff08;AI&#xff09;和Web3分别代表了智能技术和去中心化网络的两大潮流。它们的结合不仅展示了科技的无限潜力&#xff0c;还预示着我们即将迎来一个全新的互联网时代。本文将探讨AI如何驱动Web3革命&#xff0c;并实现更加智能…

RFID光触发标签在零售行业的深度应用

零售行业作为现代经济的重要组成部分&#xff0c;面临着诸多挑战和竞争压力&#xff0c;消费者需求的多样化、快速变化的市场趋势以及日益复杂的供应链管理&#xff0c;都对零售商提出了更高的要求&#xff0c;在这样的背景下&#xff0c;寻求创新的技术解决方案以提高运营效率…

CRMEB 多店版移动端商家管理功能-工作台

一、功能说明 工作台页面可查看当日总销售额&#xff0c;当日订单数、支付人数以及当日浏览量。快捷进如待处理事项页面&#xff0c;包含商家管理所有功能页面入口。 二、操作流程 1、查看销售额 商家可查看当日总销售额。当日订单数&#xff0c;支付人数以及当日浏览量。点…