<-----记录一下用Java实现存储器的分配与回收算法实现(动态分区分配)的部分过程,及源码。---->
***如界面在调试过程中出现运行界面排版等问题建议尝试将开发环境改为Intellij IDEA + jdk1.8***
一、存储器的分配与回收算法实现(动态分区分配)源码
各变量、方法、参数如有疑问请参考注释
import java.util.Scanner;
import java.util.LinkedList;
/**
* 实验:存储器的分配与回收算法实现(动态分区分配)
*
* @author xiao6ming6
* @version 1.1
*/
public class Main {
public static void main(String[] args) {
/*使用默认构造器初始化内存,默认大小为512k.如需更改请在参数填入所需内存*/
Memory my = new Memory();
Scanner sc = new Scanner(System.in);
/*menu*/
while (true) {
System.out.println("-----------------------------");
System.out.println("请参考下列内容根据需求输入序号(1-2)");
System.out.println("-----------------------------");
System.out.println("\t\t1-分配内存 \n\t\t2-释放内存 \n\t\t0-退出程序");
System.out.println("-----------------------------");
int n = 0;
/*判断输入内容是否合法*/
try {
n = sc.nextInt();
} catch (Exception e) {
throw new RuntimeException("输入数据类型不匹配 程序已终止 下次请认真输入...");
}
if (n != 1 && n != 2) {
}
/*处理分配、回收请求*/
switch (n) {
case 0:
System.exit(0);
case 1:
System.out.print("请输入要分配的内存大小:");
int size = sc.nextInt();
my.allocation(size);
my.showZones();
break;
case 2:
System.out.print("输入想要释放内存的分区号:");
int id = sc.nextInt();
my.collection(id);
break;
default:
System.out.println("输入序号有误 请重新输入!");
}
}
}
}
class Memory {
private int size;//内存大小
private static final int MIN_SIZE = 2;//最小剩余分区大小
private LinkedList<Zone> zones;//内存分区
private int pointer;//上次分配的空闲区位置
/*分区节点类-用于记录各分区状态信息*/
class Zone {
private int head;//分区始址
private int size;// 分区大小
private boolean isFree;//空闲状态
public Zone(int head, int size) {
this.head = head;
this.size = size;
this.isFree = true;
}
}
/*分别提供带参和不带参构造器 方便初始化内存*/
public Memory() {
this.size = 512;//默认内存大小512K,如有需要可自行更改
this.pointer = 0;
this.zones = new LinkedList<>();
zones.add(new Zone(0, size));
}
public Memory(int size) {
this.size = size;
this.pointer = 0;
this.zones = new LinkedList<>();
zones.add(new Zone(0, size));
}
/**
* 根据需要选择合适的动态内存分配算法
*
* @param size 请求分配分区的大小
*/
public void allocation(int size) {
System.out.println("-----------------------------");
System.out.println("\t1.FirstFit\n\t2.NextFit\n\t3.BestFit\n\t4.WorstFit");
System.out.println("-----------------------------");
System.out.print("请输入所选分配算法的序号(1-4):");
Scanner in = new Scanner(System.in);
int key = 0;
/*判断输入内容是否合法*/
try {
key = in.nextInt();
} catch (Exception e) {
throw new RuntimeException("输入数据类型不匹配 程序已终止 下次请认真输入...");
}
/*根据输入内容所选内存分配算法进行内存分配*/
switch (key) {
case 1:
firstFit(size);
break;
case 2:
nextFit(size);
break;
case 3:
bestFit(size);
break;
case 4:
worstFit(size);
break;
default:
System.out.println("输入序号有误 请重新输入!");
}
}
/**
* 首次适应算法-FirstFit
*
* @param size 请求分配分区的大小
*/
private void firstFit(int size) {
/*遍历分区链表*/
for (pointer = 0; pointer < zones.size(); pointer++) {
Zone tmp = zones.get(pointer);
/*找到可用分区(空闲且大小足够)*/
if (tmp.isFree && (tmp.size > size)) {
doAllocation(size, pointer, tmp);
return;
}
}
/*遍历结束后未找到可用分区, 则内存分配失败*/
System.out.println("无可用内存空间!");
}
/**
* 循环首次适应算法-NextFit
*
* @param size 请求分配分区的大小
*/
private void nextFit(int size) {
Zone tmp = zones.get(pointer);
if (tmp.isFree && (tmp.size > size)) {
doAllocation(size, pointer, tmp);
return;
}
int len = zones.size();
int i = (pointer + 1) % len;
for (; i != pointer; i = (i + 1) % len) {
tmp = zones.get(i);
if (tmp.isFree && (tmp.size > size)) {
doAllocation(size, i, tmp);
return;
}
}
/*遍历结束后未找到可用分区, 则内存分配失败*/
System.out.println("无可用内存空间!");
}
/**
* 最佳适应算法-BestFit
*
* @param size 请求分配分区的大小
*/
private void bestFit(int size) {
int flag = -1;
int min = this.size;
for (pointer = 0; pointer < zones.size(); pointer++) {
Zone tmp = zones.get(pointer);
if (tmp.isFree && (tmp.size > size)) {
if (min > tmp.size - size) {
min = tmp.size - size;
flag = pointer;
}
}
}
if (flag == -1) {
System.out.println("无可用内存空间!");
} else {
doAllocation(size, flag, zones.get(flag));
}
}
/**
* 最坏适应算法-WorstFit
*
* @param size 请求分配分区的大小
*/
private void worstFit(int size) {
int flag = -1;
int max = 0;
for (pointer = 0; pointer < zones.size(); pointer++) {
Zone tmp = zones.get(pointer);
if (tmp.isFree && (tmp.size > size)) {
if (max < tmp.size - size) {
max = tmp.size - size;
flag = pointer;
}
}
}
if (flag == -1) {
System.out.println("无可用内存空间!");
} else {
doAllocation(size, flag, zones.get(flag));
}
}
/**
* 内存分配
*
* @param size 分配内存大小
* @param location 分区起址
* @param tmp 新分区
*/
private void doAllocation(int size, int location, Zone tmp) {
/*若剩的比最小分区MIN_SIZE小,则把剩下那点给前一个进程*/
if (tmp.size - size <= MIN_SIZE) {
tmp.isFree = false;
} else {
Zone split = new Zone(tmp.head + size, tmp.size - size);
zones.add(location + 1, split);
tmp.size = size;
tmp.isFree = false;
}
System.out.println("成功分配 " + size + "KB 内存!");
}
/**
* 内存回收
*
* @param id 请求回收分区的编号
*/
public void collection(int id) {
if (id >= zones.size()) {
System.out.println("无此分区编号!");
return;
}
Zone tmp = zones.get(id);
int size = tmp.size;
if (tmp.isFree) {
System.out.println("指定分区未被分配, 无需回收");
return;
}
//如果回收的分区后一个是空闲就和后一个合并
if (id < zones.size() - 1 && zones.get(id + 1).isFree) {
Zone next = zones.get(id + 1);
tmp.size += next.size;
zones.remove(next);
}
//回收的分区要是前一个是空闲就和前分区合并
if (id > 0 && zones.get(id - 1).isFree) {
Zone previous = zones.get(id - 1);
previous.size += tmp.size;
zones.remove(id);
id--;
}
zones.get(id).isFree = true;
System.out.println("内存回收成功!, 本次回收了 " + size + "KB 空间!");
System.out.println("回收后内存分区情况如下:");
showZones();
}
/**
* 展示分区状况
*/
public void showZones() {
System.out.println("分区编号\t分区始址\t分区大小\t空闲状态\t");
for (int i = 0; i < zones.size(); i++) {
Zone tmp = zones.get(i);
System.out.println(i + "\t\t" + tmp.head + "\t\t" +
tmp.size + " \t" + tmp.isFree);
}
}
}
本次实验参考了https://blog.csdn.net/baidu_32045201/article/details/79048758,在原有结构上加入了自己的布局和理解,侵删。