操作系统实验之内存管理

目录

一、实验目的

二、实验内容

三、实验思路

四、实验流程图

五、主要数据结构

六、实现代码

七、运行结果


一、实验目的

通过这次实验,加深对内存管理的认识,进一步掌握内存的分配、回收算法的思想。

二、实验内容

设计程序模拟内存的动态分区内存管理方法。内存分区使用分区(说明)表进行管理,采用最先适应算法从分区表中寻找空闲区进行分配,考虑内存回收时相邻空闲区的合并。

假设初始状态下,可用的内存空间为640KB,并有下列的请求序列:

•作业1申请130KB •作业2申请60KB。

•作业3申请100KB •作业2释放60KB。

•作业4申请200KB •作业3释放100KB。

•作业1释放130KB •作业5申请140KB。

•作业6申请60KB •作业7申请50KB •作业6释放60KB。

三、实验思路

最先适应算法:将空闲区按其在存储空间中的起始地址递增的顺序排列。为作业分配存储空间时,从空闲区链的始端开始查找,选择第一个满足要求的空闲区,而不管它究竟有多大。

内存回收原理:找到当前回收的内存区间,首先判断是否和前一个区间相邻且空闲,如果相邻的话则该分区和前一分区合并,形成更大的空闲分区;若和前一空闲分区不相邻,则判断该分区是否和后一分区相邻且空闲,则该分区和后一分区合并,形成更大的空闲分区;如果该分区和前后空闲分区都不相邻,则将该分区以后的所有表目向后移动一个,形成一个新的表目并插入新释放的分区。

本实验模拟内存的动态分区内存管理方法,采用最先适应算法。定义一个链表,记录内存分配情况,并定义内存分配、回收的方法,对内存空间进行管理。

四、实验流程图

操作系统实验之内存管理_第1张图片

 操作系统实验之内存管理_第2张图片

五、主要数据结构

分区节点:包含分区被分配的作业编号、起始地址、终止地址、大小、状态。

集合:显示内存使用情况的集合,用于实现内存空间的分配、回收。

六、实现代码

//节点类:
public class Node {
	int id; // 作业id,为-1代表空闲分区;大于0代表已分配
	String name;// 作业名称
	int start; // 初始地址
	int last;// 结束地址
	int size; // 大小
	int state;
}
//主程序:
import java.util.*;
//从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,
public class FF {
    // 返回分区链表
private static List init() {
        ArrayList list = new ArrayList();
        Node node = new Node();
        // 初始化,为整个内存空间分配一个空闲节点
        node.id = -1;
        node.start = 0;
        node.last = 640;
        node.size = 640;//内存空间为640KB,高端40K用来存放操作系统。
        node.state = 0;
        list.add(node);	
        return list;
    }
 
    // 为作业id在分区链表list中分配大小为size的内存
    //1 语法public E get(int index)2 参数index:要返回的元素的索引。3 返回值返回ArrayList中指定位置的元素
    private static boolean add(List list, int id,String name, int size) {
    	Collections.sort(list, new Comparator() {
			@Override
			public int compare(Node o1, Node o2) {
				// TODO Auto-generated method stub
				return o1.start - o2.start;
			}
		});
        Node p = null;
        int i;
        // 找到第一个未分配且大于size的内存空间节点p,i为其下标
        for (i = 0; i < list.size(); i++) {
            p = list.get(i);
            if (p.id == -1 && p.size >= size)//找到大小符合的空闲区
                break;
        }
        // 当原来节点的大小大于size时需要创建一个新节点temp保留余下的分区,并插在p的后面
        if (p.size - size >= 0) {
            Node temp = new Node();//后边剩余的空间
            temp.id = -1;
            temp.start = p.start + size;
            temp.last = p.last;
            temp.size = p.size - size;
            temp.state = 0;
            list.add(temp);// 前边是p, 后边是temp
        }
        // 将原来节点变成已分配的节点并为其分配大小
        p.id = id;
        p.size = size; 
        p.last = p.start+p.size;
        p.state = 1;
        return true;
    }
    // 回收作业id的内存,并合并相邻的空闲分区
    private static boolean del(List list, int id) {
    	Collections.sort(list, new Comparator() {
			@Override
			public int compare(Node o1, Node o2) {
				// TODO Auto-generated method stub
				return o1.start - o2.start;
			}
		});
        Node p = null;
        int i;
        // 找到作业id所在的节点p,i为其下标
        for (i = 0; i < list.size(); i++) {
            p = list.get(i);
            if (p.id == id) break;//退出后获得i的大小
        }
        p.id = -1; // 回收分区
        p.state = 0;
        Node a, b;
        if (i != 0) { // 若第i-1个节点和第i个节点相邻,合并两个分区
            a = list.get(i - 1);
            b = list.get(i);
            if (a.id == -1 && b.id == -1 && a.start + a.size == b.start) {
                a.size += b.size;
                a.last = a.start+a.size;
                a.state = 0;
                list.remove(i);
//                i--;
            }
            // i--是因为可能存在合并后的节点可能与后一个节点相邻
        }
        if (i != list.size() - 1) { // 若第i个节点和第i+1个节点相邻,合并两个分区
            a = list.get(i);
            b = list.get(i + 1);
            if (a.id == -1 && b.id == -1 && a.start + a.size == b.start) {
                a.size += b.size;
                a.last = a.start+a.size;
                a.state = 0;
                list.remove(i + 1);
            }
        } 
        return true;
    }
    private static void show(List list) {
    	Collections.sort(list, new Comparator() {

			@Override
			public int compare(Node o1, Node o2) {
				// TODO Auto-generated method stub
				return o1.start - o2.start;
			}
		});
    	System.out.println("内存分配情况");
		System.out.println("作业编号\t起始地址\t终止地址\t大小\t状态");
		for (int i = 0; i < list.size(); i++) {
			Node p=list.get(i);
			if (p.id==-1) {
				System.out.println("null"+"\t"+p.start+"\t"+p.last+"\t"+p.size+"KB\t"+p.state);
			}
			else {
				System.out.println("作业"+p.id+"\t"+p.start+"\t"+p.last+"\t"+p.size+"KB\t"+p.state);
			}
		}
    }
 
    public static void main(String[] args) {
        List list = init();
        System.out.println("内存初始状态");
        System.out.println("作业编号\t起始地址\t终止地址\t大小\t状态");
        Node p=list.get(0);
		System.out.println("null"+"\t"+p.start+"\t"+p.last+"\t"+p.size+"KB\t"+p.state);
        System.out.println();
        System.out.println("-------------------------------");
//        作业1申请130KB  
        System.out.println();
        System.out.println("作业1申请130KB");
        add(list,1,"作业1",130);
        show(list);
        System.out.println("-------------------------------");
//        作业2申请60KB
        System.out.println();
        System.out.println("作业2申请60KB");
        add(list,2,"作业2",60);
        show(list);
        System.out.println("-------------------------------");
//        作业3申请100KB
        System.out.println();
        System.out.println("作业3申请100KB");
        add(list,3,"作业3",100);
        show(list);
        System.out.println("-------------------------------");
//        作业2释放60KB
        System.out.println();
        System.out.println("作业2释放60KB");
        del(list, 2);
        show(list);
        System.out.println();
        System.out.println("-------------------------------");
//        作业4申请200KB
        System.out.println();
        System.out.println("作业4申请200KB");
        add(list,4,"作业4",200);
        show(list);
        System.out.println("-------------------------------");
//        作业3释放100KB
        System.out.println();
        System.out.println("作业3释放100KB");
        del(list, 3);
        show(list);
        System.out.println("-------------------------------");
        作业1释放130KB
        System.out.println();
        System.out.println("作业1释放130KB");
        del(list, 1);
        show(list);
        System.out.println("-------------------------------");
//        作业5申请140KB
        System.out.println();
        System.out.println("作业5申请140KB");
        add(list,5,"作业5",140);
        show(list);
        System.out.println("-------------------------------");
//        作业6申请60KB
        System.out.println();
        System.out.println("作业6申请60KB");
        add(list,6,"作业6",60);
        show(list);
        System.out.println("-------------------------------");
//        作业7申请50KB
        System.out.println();
        System.out.println("作业7申请50KB");
        add(list,7,"作业7",50);
        show(list);
        System.out.println("-------------------------------");
//        作业6释放60KB
        System.out.println();
        System.out.println("作业6释放60KB");
        del(list, 6);
        show(list);
    }
}

七、运行结果

操作系统实验之内存管理_第3张图片

你可能感兴趣的:(操作系统,java)