Java实现内存分配算法 FF(首次适应算法) BF(最佳适应算法)
一、概述
因为这次os作业对用户在控制台的输入输出有要求,所以我花了挺多的代码来完善控制台的显示。
MemoryAlgorithm类里只是和控制台输入输出有关的操作,而对内存的所有逻辑操作都是用Memory类里对应的方法实现的。
因为不同内存分配算法,只有对空闲分区表的排序不同,所以可以将FF和BF等内存分配算法一起实现。
如果只关心和算法有关的核心代码的话,只看Memory类中add()、del()和sortFreeAreaList()方法即可。
添加和删除操作的逻辑比较绕,后面也有关于添加和删除操作单独的流程图。
二、运行结果
1. 测试数据:
(1)系统总内存为256,按下列参数分配内存
进程 |
1 |
2 |
3 |
4 |
5 |
6 |
所需内存 |
25 |
34 |
45 |
12 |
13 |
10 |
(2)依次回收进程2,4,3,6
(3)再次分配进程7,大小40
2. 测试结果:
(太长了,我就不截图了。测试的时候注意我的代码是按照请求回收内存的首地址进行回收的就行)
三、流程图
1. FF算法和BF算法的流程图
2. 添加进程的流程图
3. 撤销进程的流程图
四、实现代码
1. MemoryAlgorithm类(主类)
MemoryAlgorithm类只需要:
1.在适当的记录用户的输入;
2.根据用户的输入调用Memory类中对应的方法;
3.向用户反馈结果
所以这个类只是个界面。
package xqy.algorithm; import java.util.*; import xqy.been.*; /**
* @author xqy
* @date 2018年12月20日21:36:40
*
*/
public class MemoryAlgorithm {
private Memory memory;
private String algType;
private Scanner sc; /**
* Each memory algorithm uses this class.<br/><br/>
* Each memory algorithm is different only in free area's sorting. <br/><br/>
* @param algType
* FF: First fit,
* BF: Best fit
*/
public MemoryAlgorithm(String algType) {
sc = new Scanner(System.in);
this.algType = algType; init();
op();
} private void init() {
int memorySize;
int fragment; System.out.print("<" + algType + "> Please enter the memory size:");
memorySize = sc.nextInt(); System.out.print("<" + algType + "> Please enter the fragment allocated:");
fragment = sc.nextInt(); memory = new Memory(memorySize, fragment, algType);
} private void op() {
int key; while(true) {
System.out.println("\n #OPTION#");
System.out.println("1.Add Job 2.Delete Job 3.Show Current Memory 4.Exit");
System.out.print("<" + algType + "> Option:");
key = sc.nextInt();
if (key == 1) {
add();
} else if (key == 2) {
del();
} else if (key == 3) {
show();
} else if (key == 4) {
System.out.println(" #EXIT#");
return;
} else {
System.out.println(" #WRONG OPTION#");
}
}
} private void add() {
int key; while (true) {
System.out.print("<" + algType + "-add> Please enter the job size (exit: -1):");
key = sc.nextInt(); if (key == -1) {
System.out.println(" #EXIT#");
return;
} else if (key < 0) {
System.out.println(" #WRONG SIZE#");
} else { if (memory.add(key)) {
System.out.println(" #ADD RESULT# complete");
} else {
System.out.println(" #ADD RESULT# fail");
} }
}
} private void del() {
int key; while (true) {
System.out.print("<" + algType + "-del> Please enter the job first address (exit: -1):");
key = sc.nextInt(); if (key == -1) {
System.out.println(" #EXIT#");
return;
} else if (key < 0 || key >= memory.size()) {
System.out.println(" #WRONG ADDRESS#");
} else { if (memory.del(key)) {
System.out.println(" #DEL RESULT# complete");
} else {
System.out.println(" #DEL RESULT# fail");
}
}
} } private void show() {
System.out.println("<" + algType + "-current memory>");
System.out.print(memory.toString());
} public static void main(String [] args) {
Scanner sc = new Scanner(System.in);
int key; while (true) {
System.out.println("\n #OPTION#");
System.out.println("1.FF 2.BF 3.Exit");
System.out.print("Option:");
key = sc.nextInt(); if (key == 1) {
new MemoryAlgorithm("FF");
} else if (key == 2) {
new MemoryAlgorithm("BF");
} else if (key == 3) {
System.out.println(" #EXIT#");
break;
} else {
System.out.println(" #WRONG OPTION#");
}
}
}
}
2. Memory类
Memory类实现了:
1) 对内存相应属性的封装;
2) 对内存的操作:
a) add() --> 添加作业分配内存;
b) del() --> 撤销作业释放内存;
c) toString() --> 展示内存的信息;
d) sortFreeAreaList() --> 根据用户选择的内存分配算法,对“空闲空间表”进行排序(不同算法间,唯一的不同)
package xqy.been; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator; public class Memory {
private int size;
private int fragment;
private String algType;
private ArrayList<Area> freeAreaList;
private ArrayList<Area> usedAreaList; public Memory(int size, int fragment, String algType) {
this.size = size;
this.fragment = fragment;
this.algType = algType;
this.freeAreaList = new ArrayList<Area>();
this.usedAreaList = new ArrayList<Area>(); this.freeAreaList.add(new Area(size, 0, true));
} public boolean add(int newJobSize) {
boolean canAdd = false;
Area opFreeArea; for (int i = 0; i < freeAreaList.size(); i++) {
opFreeArea = freeAreaList.get(i); if (newJobSize > opFreeArea.size()) {
;
} else {
if ((opFreeArea.size() - newJobSize) <= fragment) {
usedAreaList.add(new Area(opFreeArea.size(), opFreeArea.getAddress(), false));
freeAreaList.remove(i);
} else {
int newAreaSize = opFreeArea.size() - newJobSize;
int newAreaAddress = opFreeArea.getAddress() + newJobSize;
Area newFreeArea = new Area(newAreaSize, newAreaAddress, true); usedAreaList.add(new Area(newJobSize, opFreeArea.getAddress(), false));
freeAreaList.remove(i);
freeAreaList.add(i, newFreeArea);
} canAdd = true;
sortFreeAreaList(); break;
}
} return canAdd;
} /**
* Delete job according to job`s first address.<br/><br/>
*
* If the address you entered don`t fit any used area`s first address, can`t delete.<br/><br/>
*
* If the address you entered is fight:<br/>
* <ul>
* <li>Case 1: Previous area and next area are both free.</li>
* <ul>
* <li>1.修改状态</li>
* <li>2.从used area list中删去,加进free area list</li>
* </ul>
* <li>Case 2: Previous area and next area are both used.</li>
* <ul>
* <li>1.修改最前面的分区 更改size(三个区的size之和)</li>
* <li>2.从free area list 中将next free area 删除</li>
* <li>3.从used area list 中将相应area 删除</li>
* </ul>
* <li>Case 3: Previous area is free, and next area is used.</li>
* <ul>
* <li>1.修改前面的分区 更改size(将前面分区的size和要删除分区的size合并)</li>
* <li>2.从used area list中将相应area删除</li>
* </ul>
* <li>Case 4: Previous are is used, and next area is free.</li>
* <ul>
* <li>1.修改后面的分区
* <ul>
* <li>(1)更改size(将要删除的分区的size和后面分区的size合并</li>
* <li>(2)更改address-->改成要删除分区的address </li>
* </ul>
* <li>2.从used area list中将相应area删除</li>
* </ul>
* </ul>
* @param delJobAddress
* @return
*/
public boolean del(int delJobAddress) {
boolean canDel = false;
int delAreaIndex = -1; for (int i = 0; i < usedAreaList.size(); i++) {
if (delJobAddress == usedAreaList.get(i).getAddress()) {
canDel = true;
delAreaIndex = i;
}
} if (canDel == true) {
int previousFreeAreaIndex = calcPreviousFreeAreaIndex(delJobAddress);
int nextFreeAreaIndex = calcNextFreeAreaIndex(delJobAddress, usedAreaList.get(delAreaIndex).size()); if ((previousFreeAreaIndex == -1) && (nextFreeAreaIndex == -1)) { // case 1
Area a = usedAreaList.get(delAreaIndex);
a.setFree(true); usedAreaList.remove(delAreaIndex);
freeAreaList.add(a);
} else if ((previousFreeAreaIndex >= 0) && (nextFreeAreaIndex >= 0)) { // case 2
Area preArea = freeAreaList.get(previousFreeAreaIndex);
Area needDelArea = usedAreaList.get(delAreaIndex);
Area nextArea = freeAreaList.get(nextFreeAreaIndex);
preArea.setSize(preArea.size() + needDelArea.size() + nextArea.size()); freeAreaList.remove(nextFreeAreaIndex);
usedAreaList.remove(delAreaIndex);
} else if (previousFreeAreaIndex >= 0) { // case 3
Area area = freeAreaList.get(previousFreeAreaIndex);
area.setSize(area.size() + usedAreaList.get(delAreaIndex).size());
usedAreaList.remove(delAreaIndex);
} else if (nextFreeAreaIndex >= 0) { // case 4
Area area = freeAreaList.get(nextFreeAreaIndex);
area.setSize(area.size() + usedAreaList.get(delAreaIndex).size());
area.setAddress(usedAreaList.get(delAreaIndex).getAddress());
usedAreaList.remove(delAreaIndex);
} sortFreeAreaList();
} return canDel;
} private int calcPreviousFreeAreaIndex(int address) {
int index = -1; for (int i = 0; i < freeAreaList.size(); i++) {
if ((freeAreaList.get(i).getAddress() + freeAreaList.get(i).size()) == address) {
index = i;
}
} return index;
} private int calcNextFreeAreaIndex(int address, int size) {
int index = -1; for (int i = 0; i < freeAreaList.size(); i++) {
if (freeAreaList.get(i).getAddress() == (address + size)) {
index = i;
}
} return index;
} private void sortFreeAreaList() {
if (algType.equals("FF")) {
Collections.sort(freeAreaList, new SortByAddress());
} else if (algType.equals("BF")) {
Collections.sort(freeAreaList, new SortBySize());
}
} public int size() {
return size;
} public ArrayList<Area> getFreeAreaList() {
return freeAreaList;
} @SuppressWarnings("unchecked") // 给编译器一条指令,告诉它对被批注的代码元素内部的某些警告保持静默
@Override
public String toString() {
ArrayList<Area> list = new ArrayList<Area>();
list.addAll((ArrayList<Area>)freeAreaList.clone());
list.addAll((ArrayList<Area>)usedAreaList.clone());
Collections.sort(list, new SortByAddress()); String str = " Current memory:\n";
for (int i = 0; i < list.size(); i++) {
str += " [Area] "
+ "address=" + list.get(i).getAddress() + "-" + (list.get(i).getAddress() + list.get(i).size() - 1)
+ " size=" + list.get(i).size()
+ ((list.get(i).isFree()) ? " free\n" : " used\n");
} str += " Free area List:\n";
if (freeAreaList.size() == 0) {
str += " null\n";
} else {
for (int i = 0; i < freeAreaList.size(); i++) {
str += " [Area] " + "address=" + freeAreaList.get(i).getAddress() + "-"
+ (freeAreaList.get(i).getAddress() + freeAreaList.get(i).size() - 1)
+ " size=" + freeAreaList.get(i).size() + "\n";
}
}
return str;
}
} class SortBySize implements Comparator<Area> {
public int compare(Area a1, Area a2) {
if (a1.size() > a2.size())
return 1;
return -1;
}
} class SortByAddress implements Comparator<Area> {
public int compare(Area a1, Area a2) {
if (a1.getAddress() > a2.getAddress())
return 1;
return -1;
}
}
Java实现内存分配算法 FF(首次适应算法) BF(最佳适应算法)的更多相关文章
- Java 对象内存分配与回收
JVM内存区域模型: * 程序计数器,内存区域极小,是当前线程的字节码执行行号指示器: * 虚拟机栈.本地方法栈,即平时所说的“栈”,是虚拟机用来执行方法(包括Java.非Java方法)时,使用的临时 ...
- java中内存分配策略及堆和栈的比较
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...
- JAVA虚拟机内存分配与回收机制
Java虚拟机(Java Virtual Machine) 简称JVM Java虚拟机是一个想象中的机器,在实际的计算机上通过软件模拟来实现.Java虚拟机有自己想象中的硬件,如处理器.堆栈.寄存器等 ...
- java继承内存分配
java继承内存分配 继承的基本概念: * Java不支持多继承,也就是说子类至多只能有一个父类. * 子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法. * 子类中定义的成员 ...
- 图解Java继承内存分配
图解Java继承内存分配 继承的基本概念: (1)Java不支持多继承,也就是说子类至多只能有一个父类. (2)子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法. (3)子 ...
- (转载)图解Java多态内存分配以及多态中成员方法的特点
图解Java多态内存分配以及多态中成员方法的特点 图解Java多态内存分配以及多态中成员方法的特点 Person worker = new Worker(); 子类实例对象地址赋值给父类类型引 ...
- JAVA中内存分配的问题
JAVA中内存分配的问题 1. 有这样一种说法,如今争锋于IT战场的两大势力,MS一族偏重于底层实现,Java一族偏重于系统架构.说法根据无从考证,但从两大势力各自的社区力量和图书市场已有佳作不难看出 ...
- 小白请教几个关于Java虚拟机内存分配策略的问题
最近在看周志明所著的<深入理解Java虚拟机>,有几个问题不太明白,希望对虚拟机有研究的哥们儿帮我解答一下.先说一下我进行试验的环境: 操作系统:Mac OS X 10.11.6 EI C ...
- [java,2017-05-15] 内存回收 (流程、时间、对象、相关算法)
内存回收的流程 java的垃圾回收分为三个区域新生代.老年代. 永久代 一个对象实例化时 先去看伊甸园有没有足够的空间:如果有 不进行垃圾回收 ,对象直接在伊甸园存储:如果伊甸园内存已满,会进行一次m ...
随机推荐
- ObjectARX二次开发创建自己的静态库,如同objectARX库一样
objectARX二次开发的时候,经常会用到一些重复使用的类,如果类已经足够的好,那么我们可以编译成静态库,加快开发和编译的速度,提高工作效率. 环境vs2010+objectARX2012wizar ...
- jquery源码解析:each,makeArray,merge,grep,map详解
jQuery的工具方法,其实就是静态方法,源码里面就是通过extend方法,把这些工具方法添加给jQuery构造函数的. jQuery.extend({ ...... each: function( ...
- Eclipse MarketPlace 打不开,对话框闪退
原文地址: https://blog.csdn.net/wonder_boy869/article/details/81031222 Eclipse的版本更新到了4.8.0(photon版),点击he ...
- [原创]SSH密钥访问Git仓库配置
SSH密钥并非为了解决拉取git仓库代码时,需要频繁输入密码的问题. SSH是一种比较安全的协议,可以用来免去远程登录Linux等服务器时需要输入密码的繁琐过程. 命令: ssh user@serve ...
- JAVA泛型方法与类型限定
泛型方法可以定义在普通类中,也可以定义在泛型类中 class ArrayAlg{ public static <T> T getMiddle(T...a){ return a[a.len ...
- 高阶篇:5)仿真研究Simulation studies
本章目的:了解仿真,初步学会怎么应用仿真. 1.仿真的定义 仿真------就是用模型(物理模型或数学模型)代替实际系统进行实验和研究. 把实际系统建立成物理模型或数学模型进行研究,然后把对模型实 ...
- 匈牙利算法、KM算法
PS:其实不用理解透增广路,交替路,网上有对代码的形象解释,看懂也能做题,下面我尽量把原理说清楚 基本概念 (部分来源.部分来源) 二分图: 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相 ...
- Vmtools的安装步骤
目的:实现win和centos之间的相互复制功能 1.进入centos 2.点击vm菜单的->虚拟机->安装VMware Tools 3.centos会出现一个vm的安装包 4.将文件移动 ...
- laravel 运用
查看路由:php artisan route:list 查看路由
- UML图及Visio 2010使用总结
1. 关于UML9种图的详细介绍: 参考链接A:UML 九种图详解 参考链接B:UML的九种图+包图 2. 深入探究类图: 类图间的关系:泛化 .继承.实现.依赖.关联.聚合.组合: 参考链接A:ht ...