操作系统_内存分配与回收实验报告
实验报告二主存空间的分配和回收
if(strcmp(PName,"OS")==0)
{ printf("ERROR!");
return;
}
while((strcmp(temp->proID,PName)!=0||temp->flag==1)&&temp)
temp=temp->next;
四、程序中使用的数据结构及符号说明
结构1:
typedef struct freeTable
{
char proID[6];
int startAddr; /*空闲区起始地址*/
int length; /*空闲区长度,单位为字节*/
int flag; /*空闲区表登记栏标志,用"0"表示空表项,用"1"表示未分配*/
freeNode=freeNode->next;
}
getchar();
break;
default:printf("没有该选项\n");
}/*case*/
}/*while*/
}/*main()*/
六、运行调试结果
初始界面:
分配主存,五个作业名:P1、P2、P3、P4、P5
显示主存使用情况:
回收主存P2:
if(front->flag==1&&rear->flag==1)
/* 上邻空闲区,下邻空闲区,三项合并*/
{
front->length=front->length+rear->length+temp->length;
实现内存分配实验报告(3篇)
第1篇一、实验目的1. 理解操作系统内存分配的基本原理和常用算法。
2. 掌握动态分区分配方式中的数据结构和分配算法。
3. 通过编写程序,实现内存分配和回收功能。
二、实验环境1. 操作系统:Linux2. 编程语言:C语言3. 开发工具:GCC编译器三、实验原理1. 内存分配的基本原理操作系统内存分配是指操作系统根据程序运行需要,将物理内存分配给程序使用的过程。
内存分配算法主要包括以下几种:(1)首次适应算法(First Fit):从内存空间首部开始查找,找到第一个满足条件的空闲区域进行分配。
(2)最佳适应算法(Best Fit):在所有满足条件的空闲区域中,选择最小的空闲区域进行分配。
(3)最坏适应算法(Worst Fit):在所有满足条件的空闲区域中,选择最大的空闲区域进行分配。
2. 动态分区分配方式动态分区分配方式是指操作系统在程序运行过程中,根据需要动态地分配和回收内存空间。
动态分区分配方式包括以下几种:(1)固定分区分配:将内存划分为若干个固定大小的分区,程序运行时按需分配分区。
(2)可变分区分配:根据程序大小动态分配分区,分区大小可变。
(3)分页分配:将内存划分为若干个固定大小的页,程序运行时按需分配页。
四、实验内容1. 实现首次适应算法(1)创建空闲分区链表,记录空闲分区信息,包括分区起始地址、分区大小等。
(2)编写分配函数,实现首次适应算法,根据程序大小查找空闲分区,分配内存。
(3)编写回收函数,回收程序所占用的内存空间,更新空闲分区链表。
2. 实现最佳适应算法(1)创建空闲分区链表,记录空闲分区信息。
(2)编写分配函数,实现最佳适应算法,根据程序大小查找最佳空闲分区,分配内存。
(3)编写回收函数,回收程序所占用的内存空间,更新空闲分区链表。
3. 实验结果分析(1)通过实验,验证首次适应算法和最佳适应算法的正确性。
(2)对比两种算法在内存分配效率、外部碎片等方面的差异。
五、实验步骤1. 创建一个动态内存分配模拟程序,包括空闲分区链表、分配函数和回收函数。
操作系统存储管理实验报告
操作系统存储管理实验报告一、实验目的本次实验的目的是通过编写一段程序,实现对内存的分配和回收操作,并验证算法的正确性和性能。
二、实验内容1.实现首次适应算法首次适应算法是一种动态分配的内存管理算法,通过从低地址往高地址内存块,找到第一个满足需求的空闲块进行分配。
具体实现过程如下:(1)初始化内存空间,设置内存块的大小和地址范围;(2)编写一个函数,实现内存的分配操作,根据需求大小找到第一个合适的空闲块,并在其前后设置相应的标志位;(3)编写一个函数,实现内存的回收操作,根据释放块的地址,将其前后的标志位进行合并;(4)模拟应用程序的运行,测试内存的分配和回收操作。
2.实现最佳适应算法最佳适应算法是一种动态分配的内存管理算法,通过整个内存空间,找到最小的满足需求的空闲块进行分配。
具体实现过程如下:(1)初始化内存空间,设置内存块的大小和地址范围;(2)编写一个函数,实现内存的分配操作,遍历整个内存空间,找到满足需求且大小最小的空闲块进行分配;(3)编写一个函数,实现内存的回收操作,根据释放块的地址,将其前后的标志位进行合并;(4)模拟应用程序的运行,测试内存的分配和回收操作。
三、实验结果1.首次适应算法经过测试,首次适应算法能够正确地进行内存的分配和回收操作,并且算法的性能良好。
尽管首次适应算法在分配过程中可能会产生碎片,但是由于它从低地址开始,可以在较短的时间内找到满足需求的空闲块。
在实际应用中,首次适应算法被广泛采用。
2.最佳适应算法经过测试,最佳适应算法能够正确地进行内存的分配和回收操作,并且算法的性能较好。
最佳适应算法会整个内存空间,找到大小最小的满足需求的空闲块。
因此,在分配过程中不会产生很多的碎片,但是算法的执行时间较长。
四、实验总结通过本次实验,我们成功地实现了首次适应算法和最佳适应算法,并对算法的正确性和性能进行了验证。
两种算法在内存的分配和回收过程中都表现出良好的性能,可广泛应用于实际场景中。
实验四操作系统存储管理实验报告
实验四操作系统存储管理实验报告一、实验目的本次实验的主要目的是深入理解操作系统中存储管理的基本原理和方法,通过实际操作和观察,掌握内存分配与回收、页面置换算法等关键概念,并能够分析和解决存储管理中可能出现的问题。
二、实验环境本次实验在装有 Windows 操作系统的计算机上进行,使用了 Visual Studio 等编程工具和相关的调试环境。
三、实验内容(一)内存分配与回收算法实现1、首次适应算法首次适应算法从内存的起始位置开始查找,找到第一个能够满足需求的空闲分区进行分配。
在实现过程中,我们通过建立一个空闲分区链表来管理内存空间,每次分配时从表头开始查找。
2、最佳适应算法最佳适应算法会选择能够满足需求且大小最小的空闲分区进行分配。
为了实现该算法,在空闲分区链表中,分区按照大小从小到大的顺序排列,这样在查找时能够快速找到最合适的分区。
3、最坏适应算法最坏适应算法则选择最大的空闲分区进行分配。
同样通过对空闲分区链表的排序和查找来实现。
(二)页面置换算法模拟1、先进先出(FIFO)页面置换算法FIFO 算法按照页面进入内存的先后顺序进行置换,即先进入内存的页面先被置换出去。
在模拟过程中,使用一个队列来记录页面的进入顺序。
2、最近最久未使用(LRU)页面置换算法LRU 算法根据页面最近被使用的时间来决定置换顺序,最近最久未使用的页面将被置换。
通过为每个页面设置一个时间戳来记录其最近使用的时间,从而实现置换策略。
3、时钟(Clock)页面置换算法Clock 算法使用一个环形链表来模拟内存中的页面,通过指针的移动和页面的访问标志来决定置换页面。
四、实验步骤(一)内存分配与回收算法的实现步骤1、初始化内存空间,创建空闲分区链表,并为每个分区设置起始地址、大小和状态等信息。
2、对于首次适应算法,从链表表头开始遍历,找到第一个大小满足需求的空闲分区,进行分配,并修改分区的状态和大小。
3、对于最佳适应算法,在遍历链表时,选择大小最接近需求的空闲分区进行分配,并对链表进行相应的调整。
操作系统实验四报告-主存空间分配和回收(含源码)
操作系统实验四报告-主存空间分配和回收(含源码)计算机学院计算机科学与技术专业班学号姓名教师评定_________________实验题目主存空间的分配和回收一、实验目的熟悉主存的分配与回收。
理解在不同的存储管理方式下,如何实现主存空间的分配与回收。
掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。
二、实验内容和要求主存的分配和回收的实现是与主存储器的管理方式有关的。
所谓分配,就是解决多道作业或多进程如何共享主存空间的问题。
所谓回收,就是当作业运行完成时将作业或进程所占的主存空间归还给系统。
可变分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需求,并且分区个数是可以调整的。
当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入,作业等待。
随着作业的装入、完成,主存空间被分成许多大大小小的分区,有的分区被作业占用,而有的分区是空闲的。
实验要求使用可变分区存储管理方式,分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行,分区分配中所用的算法采用首次适应算法、最佳适应算法、最差适应算法三种算法来实现主存的分配与回收。
同时,要求设计一个实用友好的用户界面,并显示分配与回收的过程。
同时要求设计一个实用友好的用户界面,并显示分配与回收的过程。
三、实验主要仪器设备和材料实验环境硬件环境:IBM-PC或兼容机软件环境:VC++ 6.0四、实验原理及设计分析某系统采用可变分区存储管理,在系统运行当然开始,假设初始状态下,可用的内存空间为640KB,存储器区被分为操作系统分区(40KB)和可给用户的空间区(600KB)。
(作业1 申请130KB、作业2 申请60KB、作业3 申请100KB 、作业2 释放 60KB 、作业4 申请 200KB、作业3释放100KB、作业1 释放130KB 、作业5申请140KB 、作业6申请60KB 、作业7申请50KB)当作业1进入内存后,分给作业1(130KB),随着作业1、2、3的进入,分别分配60KB、100KB,经过一段时间的运行后,作业2运行完毕,释放所占内存。
内存分配的实验报告
1. 理解内存分配的基本原理和常见算法。
2. 掌握动态分区分配方式中数据结构和分配算法的实现。
3. 分析不同内存分配算法的性能特点,提高对内存管理策略的认识。
二、实验环境1. 操作系统:Windows 102. 编程语言:C/C++3. 开发环境:Visual Studio 2019三、实验原理内存分配是操作系统中的一个重要功能,用于管理计算机中的内存资源。
本实验主要涉及以下内存分配算法:1. 首次适应算法(First Fit)2. 最佳适应算法(Best Fit)3. 最坏适应算法(Worst Fit)首次适应算法:从内存空间的起始位置开始查找,找到第一个足够大的空闲分区进行分配。
最佳适应算法:在整个空闲分区中查找一个大小最接近请求大小的空闲分区进行分配。
最坏适应算法:在整个空闲分区中查找一个最大的空闲分区进行分配。
四、实验步骤1. 创建一个内存空间,模拟动态分区分配方式。
2. 实现三种内存分配算法。
3. 分别使用三种算法进行内存分配,记录分配情况。
4. 分析不同算法的性能特点。
1. 创建内存空间```c#define MAX_MEMORY 1024 // 最大内存空间大小int memory[MAX_MEMORY] = {0}; // 初始化内存空间,0表示空闲int free_memory = MAX_MEMORY; // 空闲内存空间大小```2. 首次适应算法```cint first_fit(int size) {int start = 0;while (start < free_memory) {if (memory[start] == 0 && free_memory - start >= size) { for (int i = start; i < start + size; i++) {memory[i] = 1; // 分配内存}free_memory -= size;return start;}start++;}return -1; // 内存分配失败}3. 最佳适应算法```cint best_fit(int size) {int best_start = -1;int best_size = free_memory;for (int i = 0; i < free_memory; i++) {if (memory[i] == 0 && free_memory - i >= size && i < best_size) {best_start = i;best_size = i;}}if (best_start != -1) {for (int i = best_start; i < best_start + size; i++) {memory[i] = 1; // 分配内存}free_memory -= size;return best_start;}return -1; // 内存分配失败}```4. 最坏适应算法int worst_fit(int size) {int start = 0;int size_fit = 0;for (int i = 0; i < free_memory; i++) {if (memory[i] == 0 && free_memory - i >= size && free_memory - i > size_fit) {start = i;size_fit = free_memory - i;}}if (start != 0) {for (int i = start; i < start + size; i++) {memory[i] = 1; // 分配内存}free_memory -= size;return start;}return -1; // 内存分配失败}```5. 实验结果分析通过实验,我们可以观察到以下现象:- 首次适应算法分配速度较快,但可能会产生较多的内部碎片。
操作系统实验之内存管理实验报告
操作系统实验之内存管理实验报告一、实验目的内存管理是操作系统的核心功能之一,本次实验的主要目的是深入理解操作系统中内存管理的基本原理和机制,通过实际编程和模拟操作,掌握内存分配、回收、地址转换等关键技术,提高对操作系统内存管理的认识和实践能力。
二、实验环境本次实验在 Windows 操作系统下进行,使用 Visual Studio 作为编程环境,编程语言为 C++。
三、实验原理1、内存分配算法常见的内存分配算法有首次适应算法、最佳适应算法和最坏适应算法等。
首次适应算法从内存的起始位置开始查找,找到第一个满足需求的空闲分区进行分配;最佳适应算法则选择大小最接近需求的空闲分区;最坏适应算法选择最大的空闲分区进行分配。
2、内存回收算法当进程结束释放内存时,需要将其占用的内存区域回收至空闲分区链表。
回收过程中需要考虑相邻空闲分区的合并,以减少内存碎片。
3、地址转换在虚拟内存环境下,需要通过页表将逻辑地址转换为物理地址,以实现进程对内存的正确访问。
四、实验内容1、实现简单的内存分配和回收功能设计一个内存管理模块,能够根据指定的分配算法为进程分配内存,并在进程结束时回收内存。
通过模拟多个进程的内存请求和释放,观察内存的使用情况和变化。
2、实现地址转换功能构建一个简单的页式存储管理模型,模拟页表的建立和地址转换过程。
给定逻辑地址,能够正确计算出对应的物理地址。
五、实验步骤1、内存分配和回收功能实现定义内存分区的数据结构,包括起始地址、大小、使用状态等信息。
实现首次适应算法、最佳适应算法和最坏适应算法的函数。
创建空闲分区链表,初始化为整个内存空间。
模拟进程的内存请求,调用相应的分配算法进行内存分配,并更新空闲分区链表。
模拟进程结束,回收内存,处理相邻空闲分区的合并。
2、地址转换功能实现定义页表的数据结构,包括页号、页框号等信息。
给定页面大小和逻辑地址,计算页号和页内偏移。
通过页表查找页框号,结合页内偏移计算出物理地址。
内存分配回收实验报告
一、实验目的通过本次实验,加深对内存分配与回收机制的理解,掌握内存分配算法和回收策略,并能够运用所学知识解决实际内存管理问题。
二、实验内容1. 确定内存空间分配表;2. 采用首次适应算法实现内存分配;3. 采用最佳适应算法实现内存分配;4. 采用最坏适应算法实现内存分配;5. 实现内存回收功能;6. 对比分析不同内存分配算法的优缺点。
三、实验步骤1. 创建一个内存空间模拟程序,用于演示内存分配与回收过程;2. 定义内存空间分配表,记录内存块的起始地址、大小和状态(空闲或占用);3. 实现首次适应算法,在内存空间分配表中查找第一个满足条件的空闲内存块,分配给请求者;4. 实现最佳适应算法,在内存空间分配表中查找最接近请求大小的空闲内存块,分配给请求者;5. 实现最坏适应算法,在内存空间分配表中查找最大的空闲内存块,分配给请求者;6. 实现内存回收功能,当内存块释放时,将其状态更新为空闲,并合并相邻的空闲内存块;7. 对比分析不同内存分配算法的优缺点,包括分配时间、内存碎片和内存利用率等方面。
四、实验结果与分析1. 首次适应算法:该算法按照内存空间分配表的顺序查找空闲内存块,优点是分配速度快,缺点是容易产生内存碎片,且内存利用率较低;2. 最佳适应算法:该算法查找最接近请求大小的空闲内存块,优点是内存利用率较高,缺点是分配速度较慢,且内存碎片较多;3. 最坏适应算法:该算法查找最大的空闲内存块,优点是内存利用率较高,缺点是分配速度较慢,且内存碎片较多。
五、实验结论通过本次实验,我们掌握了内存分配与回收的基本原理和算法,了解了不同内存分配算法的优缺点。
在实际应用中,我们需要根据具体需求选择合适的内存分配算法,以优化内存管理,提高系统性能。
六、实验心得1. 内存分配与回收是计算机系统中重要的组成部分,对系统性能有着重要影响;2. 熟练掌握内存分配算法和回收策略,有助于解决实际内存管理问题;3. 在实际应用中,应根据具体需求选择合适的内存分配算法,以优化内存管理,提高系统性能。
操作系统-内存分配与回收实验报告
操作系统-内存分配与回收实验报告本次实验是关于内存管理的实验,主要涉及内存分配和回收的操作。
本文将对实验过程和结果进行详细介绍。
1. 实验目的本次实验的主要目的是熟悉内存管理的基本原理和机制,掌握内存分配和回收的方法,并且实现一个简单的内存管理器。
2. 实验原理内存管理是操作系统的重要组成部分,主要负责管理计算机的内存资源,并且协调进程对内存的访问。
在计算机工作过程中,内存扮演着重要的角色,因此内存管理的效率和稳定性对计算机的性能和稳定性有着重要影响。
内存管理包括内存分配和回收两个方面。
内存分配是指为进程分配空闲的内存空间,以便程序可以执行;内存回收是指将已经使用完成的内存空间还回给系统,以便其他进程使用。
3. 实验步骤为了实现一个简单的内存管理器,我们需要进行以下步骤:(1)定义内存块结构体首先,我们需要定义一个内存块结构体,用于描述内存块的基本信息。
内存块结构体可以包含以下信息:· 内存块的起始地址· 内存块是否被分配下面是一个内存块结构体定义的示例代码:typedef struct mem_block{void *start_address; // 内存块的起始地址size_t size; // 内存块的大小bool is_allocated; // 内存块是否已经分配}MemBlock;(3)实现内存分配函数现在,我们可以开始实现内存分配函数了。
内存分配函数需要完成以下工作:· 在内存管理器中寻找一个合适的内存块void *mem_alloc(MemManager *manager, size_t size){MemBlock *p = manager->block_list;while(p){if(p->size >= size && !p->is_allocated){p->is_allocated = true;return p->start_address;}p = p->next;}return NULL;}· 找到该内存块所在的位置· 将该内存块标记为未分配状态4. 实验结果本次实验实现了一个简单的内存管理器,通过该内存管理器可以实现内存分配和回收的操作。
计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告
计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告第一篇:计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告计算机操作系统实验报告实验二实验题目:存储器管理系别:计算机科学与技术系班级:姓名:学号:2一、实验目的深入理解动态分区存储管理方式下的内存空间的分配与回收。
二、实验内容编写程序完成动态分区存储管理方式下的内存分配和回收的实现。
具体内容包括:确定用来管理内存当前使用情况的数据结构;采用首次适应算法完成内存空间的分配;分情况对作业进行回收;编写主函数对所做工作进行测试。
三、实验原理分配:动态分区存储管理方式把内存除OS占用区域外的空间看作一个大的空闲区。
当作业要求装入内存时,根据作业需要内存空间的大小查询内存中各个空闲区,当从内存中找到一个大于或等于该作业大小的内存空闲区时,选择其中一个空闲区,按作业要求划出一个分区装入该作业。
回收:作业执行完后,它所占用的内存空间被收回,成为一个空闲区。
如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。
四、实验方法实现动态分区的分配与回收,主要考虑三个问题:第一、设计记录内存使用情况的数据表格,用来记录空闲区和作业占用的区域(利用结构体类型数组来保存数据);第二、在设计的数据表格基础上设计内存分配算法(采用首次适应算法找合适的分区(对空闲分区表进行排序),分配时要考虑碎片问题);第三、在设计的数据表格基础上设计内存回收算法(分四种情况进行回收(上邻、下邻、上下邻和无相邻分区)。
五、实验步骤第一,设计记录内存使用情况的数据表格λ已分配分区表:起始地址、长度、标志(0表示“空表项”,1表示“已分配”)λ空闲分区表:起始地址、长度、标志(0表示“空表项”,1表示“未分配”)struct used_table { float address;//已分分区起始地址float length;//已分分区长度,单位为字节int flag;//已分配表区登记栏标志,用0表示空栏目,char zuoyename;};//已分配区表Struct free_table[ { float address;//空闲分区起始地址float length;//空闲分区长度,单位为字节int flag;//空闲分区表登记栏目用0表示空栏目,1表示未配};//空闲分区表第二,在设计的表格上进行内存分配λ首次适应算法:为作业分配内存,要求每次找到一个起始地址最小的适合作业的分区(按起始地址递增排序)。
内存的分配与回收实验报告(最先适应法)
代码实现如下:#include <stdio.h>#include <malloc.h>#include <stdlib.h>#define n 64 //定义内存的大小int a[n],count=0;//数组a用来保存内存使用状况1为已分配0为未分配,count用来记name数组中元素个数char name[n];//已分配内存的名称(字符类型)typedef struct linknode{char pid;int start;int length;struct linknode *left,*right;}de_node; //进程节点结构体定义//head1表示未分配内存队列头指针,head2便是已分配进程队列头指针de_node *head1,*head2=NULL;struct linknode* creat()//创建一个进程节点{int len,flag1=1;//用于表示进程是否可以创建char id;struct linknode* p;p = (de_node *)malloc(sizeof(de_node));//试图在系统内存中开辟空间创建一个进程if (p==NULL) //p为空,说明系统没有可用内存用于创建此模拟进程{ printf("系统没有足够的内存可供使用!\n");//输出return(NULL);//返回空指针}printf("请输入进程id(字符类型)和长度:");//为进程输入id和分配的长度scanf("%c %d",&id,&len);fflush(stdin);//清除输入缓存if((id>='a'&&id<='z'||id>='A'&&id<='Z')&&(len>0)){for(int i=0;i<count;i++)//判断输入的进程名,如果已使用,返回空指针,并释放p指针if(name[i]==id){printf("此名称进程已存在!!");flag1=0;//标志位为0,表示下面对p指向内容不做修改free(p);return NULL;}if(len==0) {//如果输入要分配的进程长度为0,释放p,返回空指针printf("输入长度为0!\n");free(p);return(NULL);}if(flag1){//标志位1,可以对p指向内容进行修改p->pid=id; //idp->start=0; //初始开始内存位置,在以后会修改p->length=len;//长度p->left=NULL;//左指针p->right=NULL;//右指针name[count++]=id;//将id存入数组,count自加return(p);}//返回创建的进程的地址}else {printf("输入进程格式有误\n");free(p);return (NULL);}}//分配内存空间void distribute(de_node *p){ de_node *q=head1,*temp;int flag=0;do{//do_while循法//判断当前指向的内存空间的长度是否满足p所申请的长度,大于就分配if(q->length>=p->length) {p->start=q->start;//把进程的内存开始地址指向内存的可用开始地址处q->start+=p->length;//可用地址起始改变q->length-=p->length;//可用内存长度修改for(int i=p->start;i<p->start+p->length;i++)//将已分配的内存空间全部置1 a[i]=1;flag=1;//表示内存可分配//队列不止一个进程,第一个满足条件,并且刚好分配完,修改指针指向if(q->length==0&&q->right!=q) { if(q==head1)//如果第一个满足,修改头指针指向head1=q->right;q->left->right=q->right;q->right->left=q->left;free(q);//把这个已分配完的空间指针释放}}if(flag==1)//已做完处理直接跳出循环break;if(flag==0)//当前指向的内存不满足,指向下一个,继续判断是否满足q=q->right;}while(q!=head1);//搜索一遍可用内存序列if(flag==0){//没有可用的内存printf("没有满足的内存!\n");count--;//由于创建时加1,但在分配内存时失败,把1又减掉free(p);//把这个未分配到内存的进程释放}if(flag==1){//表示上面已分配好内存,并已修改内存链表,下面修改已分配内存的进程队列temp=head2;//把已分配内存的进程队列赋值给临时指针if(temp==NULL)//如果还还没有存在的任何的进程,说明当前是第一个{ head2=p;//让头指针指向第一个进程p->left=p;//双向队列第一个左右指针都指向自己p->right=p;//双向队列第一个左右指针都指向自己}else if(temp!=NULL){//已存在队列,把当前直接链到第一个,与上面的区别是指针指向head2=p;//让头指针指向p指向的进程p->left=temp->left;//p进程左边为原来第一个的左边p->right=temp;//p进程右边指向第一个temp->left->right=p;//原来第一个的左边为ptemp->left=p;//原来第一个的左边的进程为p}}}//对进程的回收void reclaim(){ char id;int flag=0;de_node *q=head2,*p=head1;if(head2==NULL)//表示当前没有进程{ printf("已没有进程!\n");}else {//已分配内存队列如果不为空printf("输入要回收的进程id:");//输入要回收进程的idscanf("%c",&id);fflush(stdin);for(int i=0;i<count;i++)//双重循环把要回收的进程找出来,并把记录的id去掉if(name[i]==id){//判断当前的进程是否满足要求for(int j=i;j<count;j++)name[j]=name[j+1];//向前覆盖name[j+1]=NULL;//置空count--;//减一}//判断是否总共只有一个进程且是够刚好也满足条件if(q->pid==id&&q->right==q&&head2==q){ head2=NULL;//把已分配队列直接置空flag=1;//表示找到满足条件的进程}if(flag==0){//上面的都没找到do{if(q->pid==id){//如果找到if(q==head2)head2=q->right;q->left->right=q->right;//修改指针指向q->right->left=q->left;flag=1;break;}else q=q->right;}while(q!=head2);}//如果找到或是遍历一遍结束if(flag==0) printf("没有此进程号!!!\n");//没有找到满足的进程if(flag==1){//表示找到了for(int i=q->start;i<q->start+q->length;i++)//释放占有的内存a[i]=0;//接下来修改可用内存的队列,while(q->start>p->start&&p->right!=head1){//从第一个开始找到回收回来的内存开始地址大的那个队列p=p->right;}if(p==head1)//表示比第一个的开始还小,那么就要修改头地址head1=q;//其他情况不用修改头地址,只需找到应该的位置,把此进程插进去q->left=p->left;//修改指针的指向q->right=p;p->left->right=q;p->left=q;if(q->start+q->length==p->start)//可以与后面合并的情况{ q->length+=p->length;//修改指针的指向p->right->left=q;q->right=p->right;free(p);}if(q->left->start+q->left->length==q->start)//可以与前面合并的情况{ q->left->length+=q->length;//修改指针的指向q->left->right=q->right;q->right->left=q->left;free(q);}}}}//打印输出void print(){ de_node *q=head2,*p=head1;if(count==0)printf("没有进程占有内存。
内存的分配与回收实验报告
内存的分配与回收实验报告实验目的:了解计算机内存分配与回收的原理及实现方式,掌握最先适应算法的具体实现,加深对内存管理的理解。
实验原理:内存是计算机系统中的关键组成部分之一,它负责存储程序运行所需的数据和指令。
为了有效管理内存,将其划分为若干个固定大小的单元,称为分配单元。
内存分配与回收的基本原则是尽量高效地利用内存空间。
最先适应算法是一种常用的内存分配算法,它的基本思想是按照内存地址从小到大的顺序,依次寻找满足分配要求的第一个空闲分区。
因为每次分配都是从低地址开始,所以能够尽量填满被回收后的可用内存空间。
实验步骤:1.定义内存块的数据结构,包括起始地址、大小、状态等信息。
2.初始化内存,划分出若干个固定大小的内存块。
3.从给定的进程请求中获取进程需要的内存大小。
4.遍历内存块列表,寻找第一个满足分配要求的空闲分区,即大小大于等于进程需求的分区。
5.如果找到了满足要求的分区,则将其划分为两个分区,一个用于分配给进程,一个作为剩余的空闲分区。
6.更新内存块列表,记录分配给进程的内存块。
7.如果没有找到满足要求的分区,则返回分配失败的信息。
8.进程完成运行后,将其占用的内存块标记为空闲,并进行合并操作,合并相邻的空闲分区。
9.更新内存块列表,记录回收的内存块。
10.重复步骤3至步骤9,直到完成所有的进程请求。
实验结果:经过多次实验,使用最先适应算法进行内存分配与回收,可以有效地利用内存空间,提高内存利用率。
实验总结:通过本次实验,我深入理解了最先适应算法的实现原理和逻辑流程。
在实际的内存管理中,我们需要根据实际情况选择合适的内存分配策略,以避免出现内存碎片和浪费现象。
同时,回收后的内存块需要及时进行合并操作,以提高内存的利用率。
实验过程中还发现,在有大量并发的情况下,最先适应算法可能会产生较多的内存碎片,影响内存的使用效率,因此需要根据实际情况选择其他适合的内存分配算法。
总之,通过这次实验,我对内存分配与回收有了更深入的理解,对内存管理算法的选择和优化也更加清晰,为以后的实际应用打下了基础。
内存分配实验报告总结(3篇)
第1篇一、实验目的本次实验旨在让学生深入理解内存分配的基本原理和不同分配算法,通过实际操作,提高学生对内存管理技术的掌握程度。
通过本次实验,我们希望达到以下目标:1. 熟悉内存分配的基本概念和过程;2. 掌握常见的内存分配算法,如首次适应算法、最佳适应算法和最坏适应算法;3. 理解内存分配中的碎片问题,并尝试解决;4. 培养学生的动手实践能力和问题解决能力。
二、实验内容1. 实验环境:使用C语言编写程序,运行在Linux操作系统上。
2. 实验步骤:(1)首次适应算法:从内存空间的起始位置开始查找,找到第一个满足申请大小的空闲分区,将其分配给请求者。
(2)最佳适应算法:从所有空闲分区中查找一个最小的满足申请大小的分区,将其分配给请求者。
(3)最坏适应算法:从所有空闲分区中查找一个最大的满足申请大小的分区,将其分配给请求者。
(4)解决内存碎片问题:采用紧凑算法,将所有空闲分区合并成一个连续的大空间,从而减少内存碎片。
三、实验过程1. 编写程序实现内存分配算法,包括内存初始化、申请内存、释放内存等功能。
2. 对不同分配算法进行测试,观察分配效果,分析不同算法的优缺点。
3. 分析内存碎片问题,尝试解决方法,如紧凑算法。
四、实验结果与分析1. 首次适应算法:该算法简单易实现,但可能导致内存利用率较低,且可能产生较大的内存碎片。
2. 最佳适应算法:该算法分配效果较好,内存利用率较高,但分配速度较慢。
3. 最坏适应算法:该算法分配效果较差,内存利用率较低,但分配速度较快。
4. 紧凑算法:通过合并空闲分区,减少了内存碎片,提高了内存利用率。
五、实验体会1. 通过本次实验,我们深入了解了内存分配的基本原理和不同分配算法,掌握了常见内存分配算法的优缺点。
2. 实验过程中,我们遇到了各种问题,如内存碎片问题、算法实现问题等,通过查阅资料、讨论和尝试,最终解决了这些问题,提高了我们的问题解决能力。
3. 实验使我们认识到,内存管理是操作系统中的一个重要组成部分,对计算机性能和稳定性有着重要影响。
《操作系统》实验报告2 可变分区存储管理方式的内存分配回收
scanf("%d",&a);
switch(a)
{case0;exit(0);
case1;
printf ("输º?入¨?作Á¡Â业°¦Ì名?J和¨ª作Á¡Â业°¦Ì所¨´需¨¨长¡è度¨¨xk:êo");
scanf("%*c%c%f",&J,&xk);
实验项目
名称
可变分区存储管理方式的内存分配回收
实验
目的及要求
1、深入了解采用可变分区存储管理方式的内存分配回收的实现
实验
内容
编写程序完成可变分区存储管理方式的内存分配回收
实验步骤
1、确定内存空间分配表
2、采用最优适应算法完成内存空间的分配和回收
3、编写主函数对所做工作进行测试
实验环境
Windows XP、visualstudio 2005
}
i++;
}
if(k!=-1)
if(j!=1)
{free_table[k].length=free_table[j].length+free_table[k].length+L;
free_table[j].flag=0;
}
else
free_table[k].length=free_table[k].length+L;
L=used_table[s].length;
j==1;k=-1;i=0;
while(i<m&&(j==-1||k==-1))
{
if(free_table[i].glag==0)
操作系统实验报告可变分区存储管理方式的内存分配回收
操作系统实验报告可变分区存储管理方式的内存分配回收集团文件发布号:(9816-UATWW-MWUB-WUNN-INNUL-DQQTY-实验三可变分区存储管理方式的内存分配回收一.实验目的(1)深入了解可变分区存储管理方式的内存分配回收的实现。
二.实验内容编写程序完成可变分区存储管理方式的内存分配回收,要求有内存空间分配表,并采用最优适应算法完成内存的分配与回收。
三.实验原理在可变分区模式下,在系统初启且用户作业尚未装入主存储器之前,整个用户区是一个大空闲分区,随着作业的装入和撤离,主存空间被分成许多分区,有的分区被占用,而有的分区时空闲的。
为了方便主存空间的分配和去配,用于管理的数据结构可由两张表组成:“已分配区表”和“未分配区表”。
在“未分配表中”将空闲区按长度递增顺序排列,当装入新作业时,从未分配区表中挑选一个能满足用户进程要求的最小分区进行分配。
这时从已分配表中找出一个空栏目登记新作业的起始地址和占用长度,同时修改未分配区表中空闲区的长度和起始地址。
当作业撤离时已分配区表中的相应状态变为“空”,而将收回的分区登记到未分配区表中,若有相邻空闲区再将其连接后登记。
可变分区的回收算法较为复杂,当一个作业撤离时,可分为4种情况:其临近都有作业(A和B),其一边有作业(A或B),其两边均为空闲区。
尤其重要的是,在程序中利用“new类型T(初值列表)”申请分配用于存放T类型数据的内存空间,利用“delete指针名”释放指针所指向的内存空间。
四.实验部分源程序#include<iostream>usingnamespacestd;typedefstructSNode{//SpaceNodeintstart,end;//起始,结束intlength;//长度大小structSNode*next;//指向下一结点的指针}*SP;SPHead=(SP)malloc(sizeof(SNode));//全局变量,内存空间头结voidDispSpace(){//显示内存空间分配情况SPp=Head->next;cout<<"\n空闲区说明表\n"<<"---地址--长度---\n";while(p){cout<<""<<p->start<<""<<p->length<<endl;p=p->next;}cout<<"----------------\n";}voidInitial(){//初始化说明表SPp,q;p=(SP)malloc(sizeof(SNode));q=(SP)malloc(sizeof(SNode));p->start=14;p->length=12;p->end=26;q->start=32;q->length=96;q->end=128;//指导书上的作业分配Head->next=p;//与头结点连接p->next=q;q->next=NULL;DispSpace();}voidAllocation(intlen){//分配内存给新作业SPp=Head->next,q;while(p){if(p->length<len)p=p->next;elseif(p->length>len){p->start=p->start+len;p->length=p->length-len;cout<<"分配成功!\n";DispSpace();return;}else{//当两者长度相等q=p->next;p->next=q->next;cout<<"分配成功!\n";DispSpace();return;}}cout<<"分配失败!\n";DispSpace();return;}voidCallBack(intsta,intlen){//回收内存SPp=Head,q=p->next,r;//开始地址和长度p->end=0;inten=sta+len;while(q){if(sta==0){//初始地址为0if(en==q->start){//正好回收q->start=0;q->length=q->end;return;}else{r=(SP)malloc(sizeof(SNode));r->start=sta;r->length=len;r->end=en; p->next=r;r->next=q;return;}}elseif((p->end<sta)&&(q->start>en)){//上邻区r=(SP)malloc(sizeof(SNode));r->start=sta;r->length=len;r->end=en;p->next=r;r->next=q;return;}elseif((p->end<sta)&&(q->start==en)){//邻区相接q->start=sta;q->length=q->end-sta;return;}elseif((p->end==sta)&&(q->start<en)){//下邻区p->end=en;p->length=en-p->start;return;}elseif(p->end==sta&&q->start==en){//邻区相接p->end=q->end;p->length=p->end-p->start;p->next=q->next;return;}else{p=p->next;q=q->next;}}}voidmain(){Initial();cout<<"现在分配大小为6K的作业4申请装入主存:"; Allocation(6);//分配时参数只有长度//--------指导书测试数据演示----------cout<<"现回收作业3(起址10,长度4)\n";CallBack(10,4);DispSpace();cout<<"现回收作业2(起址26,长度6)\n";CallBack(26,6);DispSpace();//---------------演示结束-------------system("pause");}五.实验结果与体会我的体会:。
操作系统-内存分配与回收模拟-实验06
操作系统课程实验报告
(1)首次适应算法实现
从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。
为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到高进行排序。
该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高地址空间保留大的空闲区。
(2)最佳适应算法实现
它从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区,这种方法能使碎片尽量小。
为适应此算法,空闲分区表(空闲区链)中的空闲分区要按从小到大进行排序,自表头开始查找到第一个满足要求的自由分区分配。
数据结构体分析
(3)内存回收
将释放作业所在内存块的状态改为空闲状态,删除其作业名,设置为空。
并判断该空闲块是否与其他空闲块相连,若释放的内存空间与空闲块相连时,则合并为同一个空闲块,同时修改分区大小及起始地址。
首次适配算法流程图:
最佳适配算法流程图:
内存回收:
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#define M 20
#define N 101
#define max_size 128
int i = 0,choose;
int id= 0,size = 0,countOfEmpty = 1,countOfNotEmpty = 0,num = 1;。
主存储器空间的分配和回收实验报告
主存储器空间的分配和回收实验报告主存储器是计算机中一种重要的存储设备,它用于存储程序的指令和数据。
在计算机系统中,主存储器的空间分配和回收是一个关键的问题。
为了研究主存储器空间的分配和回收,我们进行了一系列实验。
实验目的:1.了解主存储器的空间分配和回收原理;2.掌握主存储器空间分配和回收的算法和方法;3.借助实验了解主存储器空间分配和回收对系统性能的影响。
实验步骤:1.设计一个模拟的主存储器,包括地址空间和物理存储空间。
我们将地址空间划分为多个固定大小的块,每个块对应一个页面。
2.实现主存储器的空间分配算法。
我们选择了最先适应算法,即从低地址开始寻找第一个可以容纳所需页面的空闲块。
3.实现主存储器的空间回收算法。
我们选择了简单的空闲块链表算法,即将回收的空间加入到一个空闲块链表中。
4.编写测试程序,模拟实际系统中的内存分配和回收操作。
测试程序包括创建新进程,分配内存空间,释放内存空间等操作。
5.对测试程序进行性能评测,比较不同算法和策略下的主存储器使用效率和系统性能。
实验结果:通过对实验数据的分析和对比,我们得出了以下结论:1.最先适应算法在空间分配方面具有较好的效果,能够快速找到合适的空闲块。
2.简单的空闲块链表算法能够有效地回收空间,减少内存碎片的产生。
3.不同的内存分配策略会对系统性能产生影响,合理选择内存管理算法是提高系统性能的关键。
结论:本次实验通过对主存储器空间的分配和回收进行实验研究,掌握了主存储器空间分配和回收的算法和方法,并通过实验结果对主存储器的性能进行了评估和分析。
实验结果表明最先适应算法和简单的空闲块链表算法是有效的方法,能够提高主存储器的使用效率和系统性能。
在实际系统中,我们需要根据具体情况选择合适的算法和策略,以满足系统的需求。
操作系统实验报告可变分区存储管理方式的内存分配回收
操作系统实验报告可变分区存储管理方式的内存分配回收可变分区存储管理方式是一种常见的内存分配和回收策略,通过将内存分成若干大小不等的分区,分配给不同大小的进程使用。
本文将对可变分区存储管理方式的内存分配和回收进行详细介绍。
首先,可变分区存储管理方式需要对内存进行划分,将内存分成若干个大小不等的分区。
这些分区可以是固定大小的,也可以是可变大小的。
当进程申请内存时,系统会根据申请内存的大小来选择一个合适大小的分区进行分配。
分配时分为两种情况:首次适应和最佳适应。
首次适应算法是指从内存的起始位置开始遍历分区,找到第一个能满足进程要求的分区进行分配。
这种算法的优点是找到满足条件的分区速度较快,缺点是容易造成较大的内存碎片。
最佳适应算法是指通过遍历整个内存,找到一个大小最接近进程要求的分区进行分配。
这种算法的优点是能够减小内存碎片的产生,但是分配速度较慢。
当进程结束时,需要回收其占用的内存。
对于可变分区存储管理方式,在回收内存时出现了两种情况:内部碎片和外部碎片。
内部碎片是指分配给进程的分区中,有一部分空闲内存无法被其他进程利用。
这是因为当一些进程需要分配内存时,分配的大小可能大于其实际需要的大小,导致分区中留下了空余空间。
解决内部碎片的方法是动态地调整分区的大小,使其能够更好地适应进程的大小需求。
外部碎片是指存储空闲的分区之间的一些不可利用的内存。
当进程需要分配内存时,可能没有一个分区能满足其大小需求,导致无法分配内存。
解决外部碎片的方法是内存紧缩和分区合并。
内存紧缩是指将内存中的进程向一端移动,使剩余的空闲内存空间连在一起。
这样可以使得所有的空闲内存空间都可以被利用,减少外部碎片的产生。
分区合并是指将不连续的空闲分区进行合并,形成更大的连续空闲分区。
这样可以提供给大型进程使用,减少外部碎片的产生。
综上所述,可变分区存储管理方式的内存分配和回收是一个动态的过程,需要根据进程的需求进行灵活地管理。
它可以通过首次适应或最佳适应算法选择合适的分区进行内存分配,通过动态调整分区大小解决内部碎片问题,并通过内存紧缩和分区合并减少外部碎片的产生。
操作系统之内存分配与回收
操作系统实验内存的分配与回收实验报告一、实验题目:内存的分配与回收二、实验内容:利用可变分区的首次适应算法,模拟内存的分配与回收。
三、实验目的:掌握可变分区首次适应算法的原理以及其编程实现。
四、实验过程:1、基本思想:可变分区分配是根据进程的实际需求,动态地为之分配内存空间。
首次适应算法要求空闲空间链以地址递增的次序链接。
进行内存分配时,从链表头部开始依次检索,找到第一个不小于请求空间大小的空闲空间进行分配。
分配时需考虑碎片问题,若分配会导致碎片产生则将整块分区分配。
内存的回收需要考虑四种情况:⑴回收分区前后两个分区都空闲,则需要和前后两个分区合并;(2)回收分区只有前一分区空闲,则与前一分区合并;(3)回收分区只有后一分区空闲,则和后一分区合并;(4)回收分区独立,不考虑合并。
2、主要数据结构:struct FreeArea{ 链结点包含的数据:分区号、大小、起址、标记int ID;int size;long address;int sign;};struct Node { 双链表结点结构体:数据区、前向指针、后继指针FreeArea data;struct Node *prior;struct Node *next;}*DLinkList;3、输入、输出:输入: I.内存分配时由键盘输入分区ID和大小;II.内存回收时由键盘输入需要回收的分区ID;输出:输出内存的分配情况(按照地址从低到高)4、程序流程图:5、实验结果截屏:6、源程序代码:#include<iostream>using namespace std;#define Free 0 //空闲状态#define Busy 1 //已用状态#define PBusy 2 //碎片已用状态#define FINISH 1 //完成#define FINISH2 1 //完成#define ERROR 0 //出错#define memory 512 //最大内存空间为(单位:KB)#define min 10 //碎片最小值(单位:KB)typedef struct FreeArea//空闲链数据{int ID;int size;long address;int sign;};typedef struct Node//空闲连结构{FreeArea data;struct Node *prior;struct Node *next;}*DLinkList;DLinkList head; //头结点DLinkList tail; //尾结点int Create()//初始化{head=(DLinkList)malloc(sizeof(Node));//分配内存tail=(DLinkList)malloc(sizeof(Node));head->prior=NULL;head->next=tail;tail->prior=head;tail->next=NULL;tail->data.address=0;tail->data.size=memory;tail->data.ID=0;tail->data.sign=Free;return FINISH;}int FirstFit(int ID,int request)//首次适应算法{DLinkList temp=(DLinkList)malloc(sizeof(Node));//新建作业的结点temp->data.ID=ID;temp->data.size=request;temp->data.sign=Busy;Node *p=head;//插入指针Pwhile(p){if(p->data.sign==Free && p->data.size==request)//剩余大小恰好满足{p->data.sign=Busy;p->data.ID=ID;return FINISH;break;}else if(p->data.sign==Free&& p->data.size>request&& (p->data.size-request>min))//满足需求且有剩余且不产生碎片{temp->prior=p->prior;temp->next=p;temp->data.address=p->data.address;p->prior->next=temp;p->prior=temp;p->data.address=temp->data.address+temp->data.size;p->data.size=p->data.size-request;return FINISH;break;}else if(p->data.sign==Free&& p->data.size>request&& p->data.size-request<=min)//产生碎片时{p->data.sign=PBusy;p->data.ID=ID;return FINISH;break;}p=p->next;//若前面的分区都已分配,P指针后移}return ERROR;}int Allocate()//主存分配{int ID,request;cout<<"请输入作业所在分区号:";cin>>ID;cout<<"请输入分配的主存(单位:KB):";cin>>request;if(request<0 ||request==0){cout<<"分配的主存必须是正整数!"<<endl;return ERROR;}if(FirstFit(ID,request)==FINISH)cout<<"分配成功!"<<endl;elsecout<<"内存不足,分配失败!"<<endl;}int Recycle(int ID)//回收{Node *p=head;while(p){if(p->data.ID==ID){p->data.sign=Free;//p->data.ID=Free;if((p->prior->data.sign==Free)&&(p->next->data.sign==Free))//与前后的空闲块相连{p->prior->data.size=p->prior->data.size+p->data.size+p->next->data.size;p->prior->next=p->next->next;if(p->next->next==NULL)//若p->next是最后一个结点{p->prior->data.ID=Free;p->next=NULL;}else{p->next->next->prior=p->prior;}break;}if(p->prior->data.sign==Free)//与前面的空闲块相连{p->prior->data.size+=p->data.size;p->prior->next=p->next;p->next->prior=p->prior;break;}if(p->next->data.sign==Free)//与后面的空闲块相连{p->data.size+=p->next->data.size;if(p->next->next==NULL)//若p->next是最后一个结点p->next=NULL;else{p->next->next->prior=p;p->next=p->next->next;}break;}break;}p=p->next;}cout<<"分区:"<<ID<<"回收成功"<<endl;return FINISH;}void show()//显示{cout<<" 主存分配情况\n";Node *p=head->next;while(p){cout<<"分区号:";if(p->data.ID==Free)cout<<"Free"<<endl;elsecout<<p->data.ID<<endl;cout<<"起始地址:"<<p->data.address;cout<<" 分区大小:"<<p->data.size<<" KB";cout<<" 状态:";if(p->data.sign==Free)cout<<"空闲"<<endl;else if(p->data.sign==PBusy)cout<<"碎片已分配"<<endl;elsecout<<"已分配"<<endl;p=p->next;}cout<<endl;}void main(){Create();int choice;int i;for(i=0;;i++){cout<<"请输入操作:";cout<<"1.分配内存 2.回收内存 3.显示主存0.退出";cout<<endl;cin>>choice;if(choice==1)// 分配内存Allocate();else if(choice==2)// 内存回收{ i nt ID;cout<<"请输入要释放的分区号:";cin>>ID;Recycle(ID);}else if(choice==3)//显示主存show();else if(choice==0)//退出break;else//非法输入{cout<<"输入有误!"<<endl;continue;}}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
西安邮电大学(计算机学院)课内实验报告实验名称:内存分配与回收专业名称:计算机科学与技术班级:计科1503学生姓名:***学号(8位):********指导教师:***实验日期:2016年5月23日---2016年6月6日一. 实验目的及实验环境1.实验目的掌握内存分配FF,BF,WF策略及实现的思路;掌握内存回收过程及实现思路;实现内存的申请、释放的管理程序,调试运行,总结程序设计中出现的问题并找出原因,写出实验报告。
2.实验环境(1)硬件CPU:I7-6500内存:8G显示器:笔记本显示器硬盘空间:1TB(2)软件虚拟机名称及版本:Vmware操作系统名称及版本:Ubuntu Kylin 16.04编译器:gcc二. 实验内容1、实验前准备工作阅读参考资料,掌握操作系统内存管理的过程,并熟悉FF,BF,WF内存分配策略以及内存回收策略。
2、实验内容根据下发ppt内容,内存分配与回收程序要求完成如下功能,具体详细设计要求见ppt。
1 -Set memory size (default=1024)//设置内存大小2 - Select memory allocation algorithm//选择内存分配算法FF、BF、WF3 - New process//创建新进程,分配内存4 - Terminate a process//终止进程,回收内存5 - Display memory usage//显示内存当前使用情况0 – Exit//程序退出三.方案设计1.功能模块图及解释2.核心数据结构及解释struct free_block_type //空闲块{int size;int start_addr;struct free_block_type *next;};struct allocated_block //已分配的内存块{int pid;int size;int start_addr;char process_name[PROCESS_NAME_LEN];struct allocated_block *next;};1.Set memory size (default=1024):这个模块是用来设置内存大小的,从键盘获取一个数字,并将它赋值给内存大小;若没有设置,则默认内存的大小为1024。
2.Set_algorithm:这个模块是用来设置分配算法的,共有三种算法:首次循环适配算法、最好适配算法、最差适配算法。
从键盘输入一种算法前的序号,根据算法点用不同的函数对内存进行分配;3.New_process:此模块是用来创建进程的。
从键盘输入进程号,调用fork()创建进程并为其分配一定大小的内存,若分配成功,则将其连接到已分配链表中,否则分配失败;4.Kill_process:此模块是用来杀死进程的。
从键盘输入一个进程号,先调用find_process()函数进行查找,若找到,则调用kill()函数将其杀死并释放内存空间。
5.Display_mem_usage:此模块是用来显示内存的使用情况的。
将每个进程的内存使用情况显示出来,包括起始地址和内存大小;6.Do_exit:这个模块是用来结束程序的,直接调用exit()实现。
3.主要算法流程图及解释算法调用图四.测试数据及运行结果1.正常测试数据(3组)及运行结果;2.非正常测试数据(2组)及运行结果。
五.总结1.实验过程中遇到的问题及解决办法;实验过程中不会实现最佳适应算法,然后通过网上查阅别人的算法,自己研究,解决了这个问题。
2.对设计及调试过程的心得体会。
这次实验让我充分了解了内存管理的机制,进一步加深了对计算机的了解,对于以后系统的研究学习计算机起到了至关重要的作用。
六.附录:源代码(电子版)#include <stdio.h>#include <stdlib.h>#include <ctype.h>/*常量定义*/#define PROCESS_NAME_LEN 32 /*进程名长度*/#define MIN_SLICE 10 /*最小碎片的大小*/#define DEFAULT_MEM_SIZE 1024 /*内存大小*/#define DEFAULT_MEM_START 0 /*起始位置*//* 内存分配算法 */#define MA_FF 1#define MA_BF 2#define MA_WF 3/*描述每一个空闲块的数据结构*/struct free_block_type{int size;int start_addr;struct free_block_type *next;};/*每个进程分配到的内存块的描述*/struct allocated_block{int pid;int size;int start_addr;char process_name[PROCESS_NAME_LEN];struct allocated_block *next;};/*指向内存中空闲块链表的首指针*/struct free_block_type *free_block;/*进程分配内存块链表的首指针*/struct allocated_block *allocated_block_head = NULL;int mem_size=DEFAULT_MEM_SIZE; /*内存大小*/int ma_algorithm = MA_FF; /*当前分配算法*/static int pid = 0; /*初始pid*/int flag = 0; /*设置内存大小标志,防止重复设置*/ void display_menu();void do_exit();struct free_block_type *init_free_block(int mem_size);void set_mem_size();void set_algorithm();void new_process();void kill_process();void display_mem_usage();void rearrange(int choice);void abc();void rearrage_BF();void rearrage_WF();main(){char choice;pid=0;free_block = init_free_block(mem_size); //初始化空闲区display_menu();while(1) {printf("Please choice: ");fflush(stdin);choice=getchar(); //获取用户输入switch(choice) {case '1':set_mem_size(); //设置内存大小break;case '2':set_algorithm();//设置算法flag=1;break;case '3':new_process();//创建新进程flag=1; break;case '4':kill_process();//删除进程flag=1; break;case '5':display_mem_usage();//显示内存使用flag=1; break;case '0':do_exit();//释放链表并退出exit(0);default: break;}choice=getchar();}}//紧缩处理void free_memory_rearrage(int memory_reduce_size,int allocated_size) {struct free_block_type *p1,*p2;struct allocated_block *a1,*a2;if(memory_reduce_size!=0) //分配完还有小块空间{p1=free_block;p2=p1->next;p1->start_addr=0;p1->size=memory_reduce_size;p1->next=NULL;mem_size=memory_reduce_size; //}else{p2=free_block;free_block=NULL;mem_size=0;}while(p2!=NULL)//释放节点{p1=p2;p2=p2->next;free(p1);}//allocated_block 重新修改链接a1=(struct allocated_block *)malloc(sizeof(struct allocated_block));a1->pid=pid;a1->size=allocated_size;a1->start_addr=memory_reduce_size; //已申请的开始地址,从memory_reduce_size开始sprintf(a1->process_name, "PROCESS-%02d", pid);a1->next=allocated_block_head;a2=allocated_block_head;allocated_block_head=a1;while(a2!=NULL){a2->start_addr=a1->start_addr+a1->size;a1=a2;a2=a2->next;}}int allocate_mem(struct allocated_block *ab){struct free_block_type *fbt, *pre;int request_size=ab->size;//int memory_count;//计算剩余分区总内存大小fbt = pre = free_block;while((pre!=NULL)&&(request_size>pre->size))//遍历查找匹配空白区{//memory_count+=pre->size;fbt=pre;pre=pre->next;}if(!pre) //pre=pre->next结尾{if(mem_size>=request_size)/*memory_count*/{if(mem_size>=request_size+MIN_SLICE)free_memory_rearrage(mem_size-request_size,request_size); //采用紧缩技术elsefree_memory_rearrage(0,mem_size); //采用紧缩技术,空间全部分配return 0;//全部重定位,不返回上级}elsereturn -1;//分配失败!}else //内存能满足 request_size<=pre->size{if((pre->size-request_size)>MIN_SLICE)//找到可满足空闲分区且分配后剩余空间足够大,则分割{pre->size=pre->size-request_size;ab->start_addr=pre->start_addr+pre->size;}else//找到可满足空闲分区且但分配后剩余空间比较小,则一起分配,删除该节点{if(pre==fbt){fbt=pre->next;free_block=fbt;}elsefbt->next=pre->next;ab->start_addr=pre->start_addr;ab->size=pre->size;free(pre);//释放节点}}mem_size-=ab->size;//...rearrange(ma_algorithm);//分配成功,按照相应算法排序return 1;}void new_process(){struct allocated_block *ab;int size;int ret;/*ret==1表示从空闲分区分配空间成功*/if(mem_size==0){printf("内存全部分配!无法创建新进程,请先释放其他进程!\n");return;}ab=(struct allocated_block *)malloc(sizeof(struct allocated_block));if(ab==NULL){printf("No Mem!\n");exit(1);}ab->next=NULL;pid++;sprintf(ab->process_name,"PROCESS-%02d",pid);//字符串格式化ab->pid=pid;while(1){printf("Please input the memory for %s(0-%d):",ab->process_name,mem_size);scanf("%d",&size);if(size<=mem_size&&size>0){ab->size=size;break;}printf("Please input again!\n");}ret=allocate_mem(ab);//从空闲内存分配空间/*如果此时allocated_block_head尚未赋值,则赋值*/if((ret==1) &&(allocated_block_head == NULL))allocated_block_head=ab;else if(ret==1) /*分配成功,将该已分配块的描述插入已分配链表(头插<无头节点>)*/{ab->next=allocated_block_head;allocated_block_head=ab;}else if(ret==-1)/*分配不成功*/{printf("Allocation fail\n");free(ab);return;}printf("Allocation Success!\n");}struct allocated_block *find_process(int pid){struct allocated_block *p;p=allocated_block_head;while(p){if(p->pid==pid)return p;p=p->next;}return p;}/*释放ab所表示的分配区*/int free_mem(struct allocated_block *ab){int algorithm = ma_algorithm;struct free_block_type *fbt,*pre,*work;mem_size+=ab->size;fbt=(struct free_block_type *)malloc(sizeof(struct free_block_type));if(!fbt)return -1;fbt->size = ab->size;fbt->start_addr=ab->start_addr;fbt->next=NULL;rearrange(MA_FF);pre=NULL;work=free_block;//查找插入位置while((work!=NULL)&&(fbt->start_addr>work->start_addr)){pre=work;work=work->next;}if(!pre)//插入开始位置{if (!work){free_block=fbt; //}else{fbt->next=work;free_block=fbt;if(fbt->start_addr+fbt->size==work->start_addr)//2){fbt->next=work->next;fbt->size=fbt->size+work->size;free(work);}}}else{if(!work){pre->next=fbt;if(fbt->start_addr==pre->start_addr+pre->size)//1){pre->next=work;pre->size=fbt->size+pre->size;free(fbt);}}else{fbt->next=work;pre->next=fbt;// 检查并合并相邻的空闲分区if((fbt->start_addr==pre->start_addr+pre->size)&&(fbt->start_addr+fbt->size == work->start_addr))//3){pre->next=work->next;pre->size=pre->size+fbt->size+work->size;free(fbt);free(work);}else if(fbt->start_addr== pre->start_addr+pre->size)//1){pre->next=work;pre->size=pre->size+fbt->size;free(fbt);}else if(work->start_addr==fbt->start_addr+fbt->size)//2{fbt->next=work->next;fbt->size=work->size+fbt->size;free(work);}}}// 将空闲链表重新按照当前算法排序rearrange(ma_algorithm);return 1;}/*释放ab数据结构节点*/void dispose(struct allocated_block *free_ab){struct allocated_block *pre,*ab;if(free_ab==allocated_block_head)/*如果要释放第一个节点*/{allocated_block_head=free_ab->next;free(free_ab);return ;}pre=allocated_block_head;ab=allocated_block_head->next;while(ab!=free_ab){pre=ab;ab=ab->next;}pre->next=ab->next;free(ab);}void kill_process(){struct allocated_block *ab;int pid;printf("Kill process,input pid = ");scanf("%d",&pid);ab=find_process(pid);if(ab!=NULL){free_mem(ab);/*释放ab所表示的分配区*/dispose(ab);/*释放ab数据结构节点*/printf("Kill Process Success!\n");return;}printf("Kill Process Failure!\n");}/* 显示当前内存的使用情况,包括空闲区的情况和已经分配的情况 */void display_mem_usage(){struct free_block_type *fbt=free_block;struct allocated_block *ab=allocated_block_head;/* 显示空闲区 */printf("----------------------------------------------------------\n");if(fbt==NULL)printf("内存全部分配!\n");else{printf("Free Memory:\n");printf("%20s %20s\n", "\tstart_addr", " size");while(fbt!=NULL){printf("%20d %20d\n", fbt->start_addr, fbt->size);fbt=fbt->next;}}printf("----------------------------------------------------------\n");/* 显示已分配区 */if(ab==NULL)printf("尚未开始分配!\n");else{printf("\nUsed Memory:\n");printf("%10s %20s %10s %10s\n", "\tPID", " ProcessName", " start_addr ", "size");while(ab!=NULL){printf("%10d %20s %10d %10d\n", ab->pid, ab->process_name, ab->start_addr, ab->size);ab=ab->next;}}printf("----------------------------------------------------------\n");}/*按BF算法重新整理内存空闲块链表*/void rearrage_BF(){struct free_block_type *p,*p1,*p2;struct free_block_type *last_flag;p1=(struct free_block_type *)malloc(sizeof(struct free_block_type));p1->next=free_block;free_block=p1;//不改变p1,free_block指向头p1if(free_block!=NULL){for (last_flag=NULL; last_flag!=free_block; last_flag=p){for (p=p1=free_block; p1->next!=NULL&&p1->next->next!=NULL&&p1->next->next!=last_flag;p1=p1->next){if (p1->next->size > p1->next->next->size){p2 = p1->next->next;p1->next->next = p2->next; //p2->next = p1->next;p1->next = p2;p = p1->next->next;}}}}p1 = free_block;free_block = free_block->next;free(p1);p1 = NULL;}/*按WF算法重新整理内存空闲块链表*/void rearrage_WF(){struct free_block_type *p,*p1,*p2;struct free_block_type *last_flag;p1=(struct free_block_type *)malloc(sizeof(struct free_block_type));p1->next=free_block;free_block=p1;//不改变p1,free_block指向头p1if(free_block!=NULL){for (last_flag=NULL; last_flag!=free_block; last_flag=p) {for (p=p1=free_block; p1->next!=NULL&&p1->next->next!=NULL&&p1->next->next!=last_flag;p1=p1->next){if (p1->next->size < p1->next->next->size){p2 = p1->next->next;p1->next->next = p2->next; //p2->next = p1->next;p1->next = p2;p = p1->next->next;}}}}p1 = free_block;free_block = free_block->next;free(p1);p1 = NULL;}void swap(int *p ,int *q){int t;t=*p;*p=*q;*q=t;}void rearrage_FF(){struct free_block_type *tmp, *work;printf("Rearrange free blocks for FF \n");tmp = free_block;while(tmp!=NULL){ work = tmp->next;while(work!=NULL){if( work->start_addr < tmp->start_addr) { /*地址递增*/swap(&work->start_addr, &tmp->start_addr);swap(&work->size, &tmp->size);}else work=work->next;}tmp=tmp->next;}}void abc1(){struct free_block_type *p,*p1,*p2;struct free_block_type *last_flag;p1=(struct free_block_type *)malloc(sizeof(struct free_block_type));p1->next=free_block;free_block=p1;//不改变p1,free_block指向头p1if(free_block!=NULL){for (last_flag=NULL; last_flag!=free_block; last_flag=p){for (p=p1=free_block;p1->next!=NULL&&p1->next->next!=NULL &&p1->next->next!=last_flag; p1=p1->next){if (p1->next->start_addr > p1->next->next->start_addr){p2 = p1->next->next;p1->next->next = p2->next;p2->next = p1->next;p1->next = p2;p = p1->next->next;}}}}p1 = free_block;free_block = free_block->next;free(p1);p1 = NULL;}struct free_block_type *init_free_block(int mem_size){struct free_block_type *fb;fb=(struct free_block_type *)malloc(sizeof(struct free_block_type));if(fb==NULL){printf("No Mem!\n");exit(1);}fb->size=mem_size;fb->start_addr=DEFAULT_MEM_START;fb->next=NULL;return fb;}void display_menu(){printf("\n");printf(" Memory management experiment \n");printf("1 - Set memory size (default=%d)\n", DEFAULT_MEM_SIZE); printf("2 - Select memory allocation algorithm\n");printf("3 - New process \n");printf("4 - Terminate a process \n");printf("5 - Display memory usage \n");printf("0 - Exit\n");}void rearrange(int choice){switch(choice){case 1:rearrage_FF();break;case 2:rearrage_BF();break;case 3:rearrage_WF();break;}}void set_algorithm(){int algorithm;printf("\t1 - First Fit\n");printf("\t2 - Best Fit \n");printf("\t3 - Worst Fit \n");scanf("%d", &algorithm);if(algorithm>=1 && algorithm <=3)ma_algorithm=algorithm;rearrange(ma_algorithm); //按指定算法重新排列空闲区链表}void set_mem_size(){int size;if(flag!=0){printf("Cannot set memory size again or you have already started using the memory!\n");return;}printf("Total memory size =");scanf("%d", &size);if(size>0){mem_size = size;free_block->size = mem_size;}flag=1;}void do_exit(){struct free_block_type *p1,*p2;struct allocated_block *a1,*a2;p1=free_block;if(p1!=NULL){p2=p1->next;for(;p2!=NULL;p1=p2,p2=p2->next){free(p1);}free(p1);}a1=allocated_block_head;if(a1!=NULL){a2=a1->next;for(;a2!=NULL;a1=a2,a2=a2->next){free(a1);}free(a1);}}。