一、概述

  因为这次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. Echart自定义y轴刻度信息1

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  2. [Android] Android MVP 架构下 最简单的 代码实现

    Android  MVP 架构下  最简单的 代码实现 首先看图: 上图是MVP,下图是MVC MVP和MVC的区别,在于以前的View层不仅要和model层交互,还要和controller层交互.而 ...

  3. shell+crontab 实时服务进程监控重启

    #!/bin/sh #filename: checkProcess.sh #示例:每分钟检测httpd是否在运行,不在运行则重启 #crontab -e # 加入:*/ * * * * checkPr ...

  4. 实用的bash别名和函数

    本文来自于:程序师 作为一个命令行探索者,你或许发现你自己一遍又一遍重复同样的命令.如果你总是用ssh进入到同一台电脑,如果你总是将一连串命令连接起来,如果你总是用同样的参数运行一个程序,你也许希望在 ...

  5. java的排序算法

    分享网页:https://yq.aliyun.com/articles/136085?utm_content=m_26483

  6. ArchLinux下shadow服务报错

    用着Linux蓦然开机就报错了.我是个对报错很敏感的,而是是开机报错. 这个的严重性,听一位前辈说过:如果开机报错你都不理它,慢慢的它就会宕机. 报错内容: shadow服务是Linux下用于校队pa ...

  7. windows本地搭建nginx+php+mysql+redis环境详细步骤

    1.mysql的下载和安装 这个可参考我另外一篇文章:http://www.cnblogs.com/myIvan/p/9265645.html 2.php的下载和配置修改 下载地址:https://w ...

  8. Linux一些常用的基础命令,总结的很好,收藏了

    原文地址:https://www.cnblogs.com/yjd_hycf_space/p/7730690.html

  9. 51 Nod 1024 Set

    1024 矩阵中不重复的元素 1 秒 131,072 KB 10 分 2 级题   一个m*n的矩阵.   该矩阵的第一列是a^b,(a+1)^b,.....(a + n - 1)^b 第二列是a^( ...

  10. Elasticsearch 因拷贝多余的jar到lib库导致无法启动的问题

    因为需要测试,无意中拷贝了一个netty-buffer-4.1.16.Final.jar包放到es的lib目录下,晚上回家启动es的时候发现启动不起来了.检查日志发现如下错误. 其中有一句关键语句 C ...