一、概述
因为这次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.向用户反馈结果
所以这个类只是个界面。
1 package xqy.algorithm; 2 3 import java.util.*; 4 5 import xqy.been.*; 6 7 /** 8 * @author xqy 9 * @date 2018年12月20日21:36:40 10 * 11 */ 12 public class MemoryAlgorithm { 13 private Memory memory; 14 private String algType; 15 private Scanner sc; 16 17 /** 18 * Each memory algorithm uses this class.<br/><br/> 19 * Each memory algorithm is different only in free area's sorting. <br/><br/> 20 * @param algType 21 * FF: First fit, 22 * BF: Best fit 23 */ 24 public MemoryAlgorithm(String algType) { 25 sc = new Scanner(System.in); 26 this.algType = algType; 27 28 init(); 29 op(); 30 } 31 32 private void init() { 33 int memorySize; 34 int fragment; 35 36 System.out.print("<" + algType + "> Please enter the memory size:"); 37 memorySize = sc.nextInt(); 38 39 System.out.print("<" + algType + "> Please enter the fragment allocated:"); 40 fragment = sc.nextInt(); 41 42 memory = new Memory(memorySize, fragment, algType); 43 } 44 45 private void op() { 46 int key; 47 48 while(true) { 49 System.out.println(" #OPTION#"); 50 System.out.println("1.Add Job 2.Delete Job 3.Show Current Memory 4.Exit"); 51 System.out.print("<" + algType + "> Option:"); 52 key = sc.nextInt(); 53 if (key == 1) { 54 add(); 55 } else if (key == 2) { 56 del(); 57 } else if (key == 3) { 58 show(); 59 } else if (key == 4) { 60 System.out.println(" #EXIT#"); 61 return; 62 } else { 63 System.out.println(" #WRONG OPTION#"); 64 } 65 } 66 } 67 68 private void add() { 69 int key; 70 71 while (true) { 72 System.out.print("<" + algType + "-add> Please enter the job size (exit: -1):"); 73 key = sc.nextInt(); 74 75 if (key == -1) { 76 System.out.println(" #EXIT#"); 77 return; 78 } else if (key < 0) { 79 System.out.println(" #WRONG SIZE#"); 80 } else { 81 82 if (memory.add(key)) { 83 System.out.println(" #ADD RESULT# complete"); 84 } else { 85 System.out.println(" #ADD RESULT# fail"); 86 } 87 88 } 89 } 90 } 91 92 private void del() { 93 int key; 94 95 while (true) { 96 System.out.print("<" + algType + "-del> Please enter the job first address (exit: -1):"); 97 key = sc.nextInt(); 98 99 if (key == -1) { 100 System.out.println(" #EXIT#"); 101 return; 102 } else if (key < 0 || key >= memory.size()) { 103 System.out.println(" #WRONG ADDRESS#"); 104 } else { 105 106 if (memory.del(key)) { 107 System.out.println(" #DEL RESULT# complete"); 108 } else { 109 System.out.println(" #DEL RESULT# fail"); 110 } 111 } 112 } 113 114 } 115 116 private void show() { 117 System.out.println("<" + algType + "-current memory>"); 118 System.out.print(memory.toString()); 119 } 120 121 public static void main(String [] args) { 122 Scanner sc = new Scanner(System.in); 123 int key; 124 125 126 while (true) { 127 System.out.println(" #OPTION#"); 128 System.out.println("1.FF 2.BF 3.Exit"); 129 System.out.print("Option:"); 130 key = sc.nextInt(); 131 132 if (key == 1) { 133 new MemoryAlgorithm("FF"); 134 } else if (key == 2) { 135 new MemoryAlgorithm("BF"); 136 } else if (key == 3) { 137 System.out.println(" #EXIT#"); 138 break; 139 } else { 140 System.out.println(" #WRONG OPTION#"); 141 } 142 } 143 } 144 }
2. Memory类
Memory类实现了:
1) 对内存相应属性的封装;
2) 对内存的操作:
a) add() --> 添加作业分配内存;
b) del() --> 撤销作业释放内存;
c) toString() --> 展示内存的信息;
d) sortFreeAreaList() --> 根据用户选择的内存分配算法,对“空闲空间表”进行排序(不同算法间,唯一的不同)
1 package xqy.been; 2 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.Comparator; 6 7 public class Memory { 8 private int size; 9 private int fragment; 10 private String algType; 11 private ArrayList<Area> freeAreaList; 12 private ArrayList<Area> usedAreaList; 13 14 public Memory(int size, int fragment, String algType) { 15 this.size = size; 16 this.fragment = fragment; 17 this.algType = algType; 18 this.freeAreaList = new ArrayList<Area>(); 19 this.usedAreaList = new ArrayList<Area>(); 20 21 this.freeAreaList.add(new Area(size, 0, true)); 22 } 23 24 public boolean add(int newJobSize) { 25 boolean canAdd = false; 26 Area opFreeArea; 27 28 for (int i = 0; i < freeAreaList.size(); i++) { 29 opFreeArea = freeAreaList.get(i); 30 31 if (newJobSize > opFreeArea.size()) { 32 ; 33 } else { 34 if ((opFreeArea.size() - newJobSize) <= fragment) { 35 usedAreaList.add(new Area(opFreeArea.size(), opFreeArea.getAddress(), false)); 36 freeAreaList.remove(i); 37 } else { 38 int newAreaSize = opFreeArea.size() - newJobSize; 39 int newAreaAddress = opFreeArea.getAddress() + newJobSize; 40 Area newFreeArea = new Area(newAreaSize, newAreaAddress, true); 41 42 usedAreaList.add(new Area(newJobSize, opFreeArea.getAddress(), false)); 43 freeAreaList.remove(i); 44 freeAreaList.add(i, newFreeArea); 45 } 46 47 canAdd = true; 48 sortFreeAreaList(); 49 50 break; 51 } 52 } 53 54 return canAdd; 55 } 56 57 /** 58 * Delete job according to job`s first address.<br/><br/> 59 * 60 * If the address you entered don`t fit any used area`s first address, can`t delete.<br/><br/> 61 * 62 * If the address you entered is fight:<br/> 63 * <ul> 64 * <li>Case 1: Previous area and next area are both free.</li> 65 * <ul> 66 * <li>1.修改状态</li> 67 * <li>2.从used area list中删去,加进free area list</li> 68 * </ul> 69 * <li>Case 2: Previous area and next area are both used.</li> 70 * <ul> 71 * <li>1.修改最前面的分区 更改size(三个区的size之和)</li> 72 * <li>2.从free area list 中将next free area 删除</li> 73 * <li>3.从used area list 中将相应area 删除</li> 74 * </ul> 75 * <li>Case 3: Previous area is free, and next area is used.</li> 76 * <ul> 77 * <li>1.修改前面的分区 更改size(将前面分区的size和要删除分区的size合并)</li> 78 * <li>2.从used area list中将相应area删除</li> 79 * </ul> 80 * <li>Case 4: Previous are is used, and next area is free.</li> 81 * <ul> 82 * <li>1.修改后面的分区 83 * <ul> 84 * <li>(1)更改size(将要删除的分区的size和后面分区的size合并</li> 85 * <li>(2)更改address-->改成要删除分区的address </li> 86 * </ul> 87 * <li>2.从used area list中将相应area删除</li> 88 * </ul> 89 * </ul> 90 * @param delJobAddress 91 * @return 92 */ 93 public boolean del(int delJobAddress) { 94 boolean canDel = false; 95 int delAreaIndex = -1; 96 97 for (int i = 0; i < usedAreaList.size(); i++) { 98 if (delJobAddress == usedAreaList.get(i).getAddress()) { 99 canDel = true; 100 delAreaIndex = i; 101 } 102 } 103 104 if (canDel == true) { 105 int previousFreeAreaIndex = calcPreviousFreeAreaIndex(delJobAddress); 106 int nextFreeAreaIndex = calcNextFreeAreaIndex(delJobAddress, usedAreaList.get(delAreaIndex).size()); 107 108 if ((previousFreeAreaIndex == -1) && (nextFreeAreaIndex == -1)) { // case 1 109 Area a = usedAreaList.get(delAreaIndex); 110 a.setFree(true); 111 112 usedAreaList.remove(delAreaIndex); 113 freeAreaList.add(a); 114 } else if ((previousFreeAreaIndex >= 0) && (nextFreeAreaIndex >= 0)) { // case 2 115 Area preArea = freeAreaList.get(previousFreeAreaIndex); 116 Area needDelArea = usedAreaList.get(delAreaIndex); 117 Area nextArea = freeAreaList.get(nextFreeAreaIndex); 118 preArea.setSize(preArea.size() + needDelArea.size() + nextArea.size()); 119 120 freeAreaList.remove(nextFreeAreaIndex); 121 usedAreaList.remove(delAreaIndex); 122 } else if (previousFreeAreaIndex >= 0) { // case 3 123 Area area = freeAreaList.get(previousFreeAreaIndex); 124 area.setSize(area.size() + usedAreaList.get(delAreaIndex).size()); 125 usedAreaList.remove(delAreaIndex); 126 } else if (nextFreeAreaIndex >= 0) { // case 4 127 Area area = freeAreaList.get(nextFreeAreaIndex); 128 area.setSize(area.size() + usedAreaList.get(delAreaIndex).size()); 129 area.setAddress(usedAreaList.get(delAreaIndex).getAddress()); 130 usedAreaList.remove(delAreaIndex); 131 } 132 133 sortFreeAreaList(); 134 } 135 136 return canDel; 137 } 138 139 private int calcPreviousFreeAreaIndex(int address) { 140 int index = -1; 141 142 for (int i = 0; i < freeAreaList.size(); i++) { 143 if ((freeAreaList.get(i).getAddress() + freeAreaList.get(i).size()) == address) { 144 index = i; 145 } 146 } 147 148 return index; 149 } 150 151 private int calcNextFreeAreaIndex(int address, int size) { 152 int index = -1; 153 154 for (int i = 0; i < freeAreaList.size(); i++) { 155 if (freeAreaList.get(i).getAddress() == (address + size)) { 156 index = i; 157 } 158 } 159 160 return index; 161 } 162 163 private void sortFreeAreaList() { 164 if (algType.equals("FF")) { 165 Collections.sort(freeAreaList, new SortByAddress()); 166 } else if (algType.equals("BF")) { 167 Collections.sort(freeAreaList, new SortBySize()); 168 } 169 } 170 171 public int size() { 172 return size; 173 } 174 175 public ArrayList<Area> getFreeAreaList() { 176 return freeAreaList; 177 } 178 179 @SuppressWarnings("unchecked") // 给编译器一条指令,告诉它对被批注的代码元素内部的某些警告保持静默 180 @Override 181 public String toString() { 182 ArrayList<Area> list = new ArrayList<Area>(); 183 list.addAll((ArrayList<Area>)freeAreaList.clone()); 184 list.addAll((ArrayList<Area>)usedAreaList.clone()); 185 Collections.sort(list, new SortByAddress()); 186 187 String str = " Current memory: "; 188 for (int i = 0; i < list.size(); i++) { 189 str += " [Area] " 190 + "address=" + list.get(i).getAddress() + "-" + (list.get(i).getAddress() + list.get(i).size() - 1) 191 + " size=" + list.get(i).size() 192 + ((list.get(i).isFree()) ? " free " : " used "); 193 } 194 195 str += " Free area List: "; 196 if (freeAreaList.size() == 0) { 197 str += " null "; 198 } else { 199 for (int i = 0; i < freeAreaList.size(); i++) { 200 str += " [Area] " + "address=" + freeAreaList.get(i).getAddress() + "-" 201 + (freeAreaList.get(i).getAddress() + freeAreaList.get(i).size() - 1) 202 + " size=" + freeAreaList.get(i).size() + " "; 203 } 204 } 205 return str; 206 } 207 } 208 209 class SortBySize implements Comparator<Area> { 210 public int compare(Area a1, Area a2) { 211 if (a1.size() > a2.size()) 212 return 1; 213 return -1; 214 } 215 } 216 217 class SortByAddress implements Comparator<Area> { 218 public int compare(Area a1, Area a2) { 219 if (a1.getAddress() > a2.getAddress()) 220 return 1; 221 return -1; 222 } 223 }