要求:
1、在该实验中,采用可变分区方式完成对存储空间的管理(即存储空间的分配与回收工作)。
2、设计用来记录主存使用情况的数据结构:已分区表和空闲分区表。
3、在设计好的数据结构上设计一个主存分配算法,要求实现的基本功能操作有:寻找空闲分区,空闲分区表的修改,已分区表的修改。
4、在设计好的数据结构上设计一个主存回收算法。其中,若回收的分区有上邻空闲分区和(或)下邻空闲分区,要求合并为一个空闲分区登记在空闲分区表的一个表项里。
代码实现:
//Main.java
package test;
import java.util.Scanner;
public class Main {public static void main(String[] args) {Scanner s = new Scanner(System.in);System.out.print("请输入内存总大小: ");int totalSize = s.nextInt();RAMManager manager = new RAMManager(totalSize);manager.disPlay();while (true) {System.out.println("\n请选择操作:");System.out.println("分配内存:1");System.out.println("回收内存:2");System.out.println("退出:3");int choice = s.nextInt();if (choice == 3) break;switch (choice) {case 1:System.out.print("请输入进程名: ");String name = s.next();System.out.print("请输入分配的内存大小: ");int size = s.nextInt();if (manager.allocate(name, size)) {System.out.println("分配成功!");} else {System.out.println("分配失败! 没有足够的连续空间.");}manager.disPlay();break;case 2:System.out.print("请输入要回收内存的进程名: ");name = s.next();if (manager.breakSpace(name)) {System.out.println("回收成功!");} else {System.out.println("回收失败! 未找到该进程.");}manager.disPlay();break;default:System.out.println("无效选择!");}}s.close();System.out.println("程序结束!");}
}
//RAM.java
package test;
public class RAM {//分区类int start; // 起始地址int size; // 分区大小boolean free; // 是否空闲String name; // 进程名public RAM(int start, int size, boolean free, String name) {this.start = start;this.size = size;this.free = free;this.name = name;}
}
//RAMManager.java
package test;
import java.util.ArrayList;
import java.util.Comparator;
public class RAMManager { // 内存管理器类ArrayList<RAM> alreadyTable; // 已分配分区表ArrayList<RAM> freeTable; // 空闲分区表int sumSize; // 内存总大小public RAMManager(int sumSize) { // 初始化this.sumSize = sumSize;alreadyTable = new ArrayList<>();freeTable = new ArrayList<>();freeTable.add(new RAM(0, sumSize, true, ""));}public boolean allocate(String name, int size) { // 首次适应算法分配内存for (int i = 0; i < freeTable.size(); i++) { // 找合适的空闲分区RAM p = freeTable.get(i);if (p.size >= size) {alreadyTable.add(new RAM(p.start, size, false, name));// 分配空闲分区if (p.size > size) {// 更新空闲分区p.start += size;p.size -= size;} else {freeTable.remove(i); // 若分配完移除该空闲分区}alreadyTable.sort(Comparator.comparingInt(part -> part.start));// 按起始地址排序已分配表return true;}}return false; // 分配失败}public boolean breakSpace(String name) { // 回收内存for (int i = 0; i < alreadyTable.size(); i++) { // 查找要回收的分区RAM p = alreadyTable.get(i);if (p.name.equals(name)) {alreadyTable.remove(i); // 从已分配表中移除RAM freePart = new RAM(p.start, p.size, true, "");// 将已回收的分区加入空闲表freeTable.add(freePart); mergeFreePartitions(); // 合并相邻的空闲分区freeTable.sort(Comparator.comparingInt(part -> part.start));// 按起始地址排序空闲表return true;}}return false; // 回收失败(未找到该进程)}private void mergeFreePartitions() { // 合并相邻的空闲分区freeTable.sort(Comparator.comparingInt(part -> part.start));// 按地址排序for (int i = freeTable.size() - 1; i > 0; i--) {// 从后向前合并RAM prev = freeTable.get(i - 1);RAM curr = freeTable.get(i);if (prev.start + prev.size == curr.start) { // 检查是否相邻prev.size += curr.size; // 合并分区freeTable.remove(i); }}}public void disPlay() { // 打印各个表状态System.out.println("\n当前内存状态:");System.out.println("\n空闲分区表:");System.out.println(" 起始地址 大小");for (RAM p : freeTable) {System.out.printf("%8d\t%d\n", p.start, p.size);}System.out.println("已分配分区表:");System.out.println(" 起始地址 大小 进程名");for (RAM p : alreadyTable) {System.out.printf("%8d\t%d\t%s\n", p.start, p.size, p.name);}}
}
核心代码流程图:
内存分配流程图
内存回收流程图
运行结果:
初始化内存空间,将进程p1装入内存中
将p2装入内存中
装入p3时发现内存不足
将进程p2回收后再次装入p3,内存空间充足,成功装入