一、概述

  因为这次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. 跑monkey前开启/关闭系统通知栏

    @echo off cls title 别忘了跑monkey啊 :menu cls color 0A echo. .禁用systemui并重启 echo. .启用systemui并重启 echo. e ...

  2. typescript项目中import 图片时报错:TS2307: Cannot find module ‘...’

    最近在用typescript写项目时,我用import来加载一个图片,webpack编译文件是会报错如下: 报错: 解决: 如果在js中引入本地静态资源图片时使用import img from './ ...

  3. js实现checkbox全选,全部选和反选效果

    效果: 源码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  4. ES6 (一)变量声明方法 & 解构赋值

    就是最新的JavaScript 原来的是var,要求不严格,不能限制修改,函数级 es6要求严格 1.防止重复声明 let      变量=var const 常量 2.控制修改 const常量不能修 ...

  5. Linux进程间通信——使用System V 消息队列

    消息队列 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法. 每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构.我们可以通过发送消息来避免命名管道的同步和阻塞问 ...

  6. 什么是hive

    Hadoop Hive概念学习系列之什么是Hive? 参考  <Hadoop大数据分析与挖掘实战>的在线电子书阅读                   http://yuedu.baidu ...

  7. Doc/Docx/PDF to Html

    TODO 判断源文件是否有格式??

  8. oracle for update for update nowait

    对数据进行查询操作后,或提示ORA-00054错误,这时选定行的资源被占用,资源正忙.其他程序或者用户在占用着此行数据或者此表. 直接查询. select * from A1 t  ; 此时取到的数据 ...

  9. 进阶篇:5.1)极值法(Worst Case ,WC)

    本章目的:了解极值法,运用极值法: 1.极值法定义 极值法(WC,Worse Case):极值法是考虑零件尺寸最不利的情况,通过尺寸链中尺寸的最大值或最小值来计算关键尺寸的值: 计算公式: 2.极值法 ...

  10. BFS - 20190206

    1.二叉树 BFS 2.拓扑排序  重点 BFS 3.棋盘上的宽搜  BFS 图的遍历 层级遍历,由点及面,拓扑排序,简单图的最短路径 如果题目问最短路径:可能是BFS或者DP, 最长路径:DFS q ...