一、概述

  因为这次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(最佳适应算法)的更多相关文章

  1. Java 对象内存分配与回收

    JVM内存区域模型: * 程序计数器,内存区域极小,是当前线程的字节码执行行号指示器: * 虚拟机栈.本地方法栈,即平时所说的“栈”,是虚拟机用来执行方法(包括Java.非Java方法)时,使用的临时 ...

  2. java中内存分配策略及堆和栈的比较

    Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...

  3. JAVA虚拟机内存分配与回收机制

    Java虚拟机(Java Virtual Machine) 简称JVM Java虚拟机是一个想象中的机器,在实际的计算机上通过软件模拟来实现.Java虚拟机有自己想象中的硬件,如处理器.堆栈.寄存器等 ...

  4. java继承内存分配

    java继承内存分配 继承的基本概念: * Java不支持多继承,也就是说子类至多只能有一个父类. * 子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法. * 子类中定义的成员 ...

  5. 图解Java继承内存分配

    图解Java继承内存分配   继承的基本概念: (1)Java不支持多继承,也就是说子类至多只能有一个父类. (2)子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法. (3)子 ...

  6. (转载)图解Java多态内存分配以及多态中成员方法的特点

    图解Java多态内存分配以及多态中成员方法的特点   图解Java多态内存分配以及多态中成员方法的特点   Person worker = new Worker(); 子类实例对象地址赋值给父类类型引 ...

  7. JAVA中内存分配的问题

    JAVA中内存分配的问题 1. 有这样一种说法,如今争锋于IT战场的两大势力,MS一族偏重于底层实现,Java一族偏重于系统架构.说法根据无从考证,但从两大势力各自的社区力量和图书市场已有佳作不难看出 ...

  8. 小白请教几个关于Java虚拟机内存分配策略的问题

    最近在看周志明所著的<深入理解Java虚拟机>,有几个问题不太明白,希望对虚拟机有研究的哥们儿帮我解答一下.先说一下我进行试验的环境: 操作系统:Mac OS X 10.11.6 EI C ...

  9. [java,2017-05-15] 内存回收 (流程、时间、对象、相关算法)

    内存回收的流程 java的垃圾回收分为三个区域新生代.老年代. 永久代 一个对象实例化时 先去看伊甸园有没有足够的空间:如果有 不进行垃圾回收 ,对象直接在伊甸园存储:如果伊甸园内存已满,会进行一次m ...

随机推荐

  1. PL/SQL那点事-->SqlSession operation; SQL []; ORA-01722: 无效数字

    PL/SQL那点事-->SqlSession operation;SQL []; ORA-01722: 无效数字 出现这种情况,在网上查了很多方法:大致主要有两种方法帮助我们解决这个问题: 1. ...

  2. TCP的成块数据流

    TCP使用滑动窗口协议的另一种方式来实现流量控制.该协议允许发送方在停止并等待确认之前可以连续发送多个分组.由于发送方不必每发送一个分组就停下来等确认,因此该协议可以加速数据的传输. 一.滑动窗口  ...

  3. 通过Maven简单搭建SSM框架

    创建Maven就不用多说了,下面直接看Pom.xml里面的依赖吧 <properties> <!-- spring版本号 --> <spring.version>5 ...

  4. SQL总结----存储过程

    概念 存储过程(Stored Procedure):已预编译为一个可执行过程的一个或多个SQL语句. 创建存储过程语法 CREATE proc | procedure procedure_name [ ...

  5. 「DB」数据库事务的隔离级别

    *博客搬家:初版发布于 2017/04/10 00:37    原博客地址:https://my.oschina.net/sunqinwen/blog/875833 数据库事务的隔离级别 讲事务的隔离 ...

  6. C#集合之可观察的集合

    如果需要集合中的元素何时删除或添加的信息,可以使用ObservableCollection<T>类.这个类是为WPF定义的,这样UI就可以得知集合的变化.这个类在程序集WindowsBas ...

  7. 2019 CCPC-Wannafly Winter Camp Day5(Div2, onsite)

    solve 5/11 补题:7/11 A Cactus Draw Code:zz Thinking :zz 题意:要在n*n的网格内画上一棵节点数为n树,使得没有边相交. 很好想的构造题,因为网格有n ...

  8. Vue.js路由跳转带参数到模板组件。

    从SalesOrderQuery组件跳到SalesOrder组件,并且通过params属性携带数据. handleClick(row) { //alert(row.FSaleName);//获取该行F ...

  9. element-ui日期组件DatePicker选择日期范围赋值编辑问题

    最近在项目中使用element-UI的日期范围组件时遇到一个问题,相信很多人也做过这种场景,一个录入页面也同时是编辑页面,编辑的时候就需要先赋值.但是我给date组件赋值后,确无法操作了,change ...

  10. gVim安装vim-template插件后提示Undefined variable vim_template_subtype/Press ENTER or type command to continue

    Win7 64位 gVim:version 8.1.1234 vim-template:github链接 安装方式: 直接下载master的zip压缩包,解压后放入本地gVim安装目录的plugin, ...