要求:
????????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,內存空間充足,成功裝入