存储器的分配与回收算法实现

实验要求:

1.本实验是模拟操作系统的主存分配,运用可变分区的存储管理算法设计主存分配和回收程序,并不实际启动装入作业。

2.采用最先适应法、最佳适应法、最坏适应法分配主存空间。

3. 当一个新作业要求装入主存时,必须查空闲区表,从中找出一个足够大的空闲区。若找到的空闲区大于作业需要量,这时应把它分成二部分,一部分为占用区,剩余部分又成为一个空闲区。

4.当一个作业撤离时,归还的区域如果与其他空闲区相邻,则应合并成一个较大的空闲区,登在空闲区表中。

5.运行所设计的程序,输出有关数据结构表项的变化和内存的当前状态。

代码:

  1 /*
  2  * author by Zephery Wen
  3  * Date 2015.12.24
  4  */
  5 import java.util.ArrayList;
  6 import java.util.Scanner;
  7 import java.util.Vector;
  8
  9 /*===============进程控制块===================*/
 10 class PCB {
 11     String name;            //记录控制块的名字
 12     int memory;                //记录存储块的容量
 13
 14     public String getName() {
 15         return name;
 16     }
 17
 18     public void setName(String name) {
 19         this.name = name;
 20     }
 21
 22     public int getMemory() {
 23         return memory;
 24     }
 25
 26     public void setMemory(int memory) {
 27         this.memory = memory;
 28     }
 29 }
 30
 31 /* ==================存储块=============================== */
 32 class Memorys {
 33     String name;
 34     int size;
 35     String station = "空闲";
 36
 37     public String getName() {
 38         return name;
 39     }
 40
 41     public void setName(String name) {
 42         this.name = name;
 43     }
 44
 45     public int getSize() {
 46         return size;
 47     }
 48
 49     public void setSize(int size) {
 50         this.size = size;
 51     }
 52
 53     public String getStation() {
 54         return station;
 55     }
 56
 57     public void setStation(String station) {
 58         this.station = station;
 59     }
 60
 61     public String toString() {
 62         String str = "\t" + this.name + "\t" + this.size + "\t" + this.station;
 63         return str;
 64     }
 65 }
 66
 67 // ====================================================================
 68 class Methid {                                            //存储块用的是List
 69     public void swap(ArrayList<Memorys> list) {            //swap方法排序
 70         System.out.println("将存储块大小进行排序之后:");
 71         for (int i = 0; i < list.size() - 1; i++) {          //冒泡排序
 72             for (int j = i; j < list.size(); j++) {
 73                 if (list.get(i).size > list.get(j).size) {
 74                     Object obj = list.get(i);
 75                     list.set(i, list.get(j));
 76                     list.set(j, (Memorys) obj);
 77                 }
 78             }
 79         }
 80     }
 81
 82     public void print(ArrayList<Memorys> list) {             //输出
 83         System.out.println("\t存储块名\t存储大小\t存储状态");
 84         for (int i = 0; i < list.size(); i++) {
 85             System.out.println(list.get(i));
 86         }
 87     }
 88 }
 89
 90 // =================================================================
 91 class Access {
 92     Scanner input = new Scanner(System.in);
 93     Methid methid = new Methid();
 94
 95     public void mainMethid(String str, Vector<PCB> pcbs, ArrayList<Memorys> list) {
 96         while (true) {
 97             System.out.println("请输入你要操作的步骤:");
 98             System.out.print("  1:运行进程");
 99             System.out.print("  2:结束进程");
100             System.out.println("  3:结束当前算法");
101             System.out.print("请输入:");
102             int p = input.nextInt();
103             if (p == 1) {             /*----------运行进程运行进程运行进程-------------------*/
104                 System.out.println("请输入当前要运行的进程名");
105                 String name = input.next();
106                 for (int i = 0; i < pcbs.size(); i++) {
107                     if (name.equals(pcbs.get(i).name)) {       //输入要运行的进程名和第i个PCB的名字相同
108                         /*将空闲区按其在存储空间中的起始地址递增的顺序排列。为作业分配存储空间时,从空闲区链的始端开始
109                         *查找,选择第一个满足要求的空闲区,而不管它究竟有多大。*/
110                         if (str.equals("A")) {                    //-----------如果输入A,最先适应法
111                             for (int j = 0; j < list.size(); j++) {
112                                 if (list.get(j).size >= pcbs.get(i).memory && list.get(j).station.equals("空闲")) {
113                                     Memorys memorys = new Memorys();
114                                     list.get(j).setStation(name + "正在运行");
115                                     int beyond = 0;                    //初始化beyond
116                                     beyond = list.get(j).size - pcbs.get(i).memory;     //beyond=存储块大小-pcb的所占内存大小
117                                     if (beyond != 0) {
118                                         list.get(j).setSize(pcbs.get(i).memory);
119                                         list.add(j + 1, memorys);
120                                         list.get(j + 1).setName("子存储块");
121                                         list.get(j + 1).setSize(beyond);
122                                     }
123                                     methid.print(list);
124                                     break;
125                                 }
126                             }
127                         }
128                         /*最佳适应算法是从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区的一种计算方法,这种方法能使碎片尽量小。*/
129                         else if (str.equals("B")) {            //----------------如果输入B,最佳适应法
130                             Memorys memorys = new Memorys();
131                             int beyond = 100;
132                             int ss = -1;
133                             for (int j = 0; j < list.size(); j++) {
134                                 if (list.get(j).size >= pcbs.get(i).memory && list.get(j).station.equals("空闲")) {
135                                     if ((list.get(j).size - pcbs.get(i).memory) < beyond) {
136                                         beyond = list.get(j).size - pcbs.get(i).memory;
137                                         ss = j;
138                                     }
139                                 }
140                             }
141                             if (beyond != -1) {
142                                 list.get(ss).setStation(name + "正在运行");
143                                 list.get(ss).setSize(pcbs.get(i).memory);
144                                 if (beyond != 0) {
145                                     list.add(ss + 1, memorys);
146                                     list.get(ss + 1).setName("子存储块");
147                                     list.get(ss + 1).setSize(beyond);
148                                 }
149                             }
150                             methid.print(list);
151                             break;
152                         }
153                         /*最坏适应分配算法要扫描整个空闲分区或链表,总是挑选一个最大的空闲分区分割给作业使用。该算法
154                          * 要求将所有的空闲分区按其容量从大到小的顺序形成一空闲分区链,查找时只要看第一个分区能否满足作业要求。*/
155                         else if (str.equals("C")) {                //-----------如果输入C,最坏适应法
156                             Memorys memorys = new Memorys();
157                             int beyond = -1;
158                             int ss = -1;
159                             for (int j = 0; j < list.size(); j++) {
160                                 if (list.get(j).size > pcbs.get(i).memory && list.get(j).station.equals("空闲")) {
161                                     if ((list.get(j).size - pcbs.get(i).memory) > beyond) {
162                                         beyond = list.get(j).size - pcbs.get(i).memory;
163                                         ss = j;
164                                     }
165                                 }
166
167                             }
168                             if (ss != -1) {
169                                 list.get(ss).setStation(name + "正在运行");
170                                 list.get(ss).setSize(pcbs.get(i).memory);
171                                 if (beyond != 0) {
172                                     list.add(ss + 1, memorys);
173                                     list.get(ss + 1).setName("字存储块");
174                                     list.get(ss + 1).setSize(beyond);
175                                 }
176                             }
177                             methid.print(list);
178                             break;
179                         }
180                     }
181                 }
182             } else if (p == 2) {          /*--------------------结束进程---------------*/
183                 System.out.println("请输入要结束的进程名");
184                 String name = input.next();
185                 String names = name + "正在运行";
186                 for (int i = 0; i < list.size(); i++) {
187                     if (names.equals(list.get(i).station)) {
188                         list.get(i).setStation("空闲");
189                         if (list.get(i + 1).name.equals("字存储块")) {
190                             list.get(i).size = list.get(i).size + list.get(i + 1).size;
191                             list.remove(i + 1);
192                         }
193                         methid.print(list);
194                         break;
195                     }
196                 }
197             } else if (p == 0) {          /*-----------------结束当前算法-------------------*/
198                 for (int i = 0; i < list.size(); i++) {
199                     if (list.get(i).getStation() != "空闲") {
200                         list.get(i).setStation("空闲");
201                         if (list.get(i + 1).name.equals("字存储块")) {
202                             list.get(i).size = list.get(i).size + list.get(i + 1).size;
203                             list.remove(i + 1);
204                         }
205                     }
206                 }
207                 break;
208             }
209         }
210     }
211 }
212
213 // ======================================主方法==================================
214 public class test {
215     private static Scanner input;
216
217     public static void main(String args[]) {
218         Vector<PCB> pcbs = new Vector<PCB>();
219         System.out.println("请输入进程数:");
220         Scanner input = new Scanner(System.in);
221         int n = input.nextInt();
222         for (int i = 0; i < n; i++) {
223             PCB pcb = new PCB();
224             System.out.println("请输入第" + (i + 1) + "个进程的名字/运行所占内存用空格隔开");
225             pcb.name = input.next();
226             pcb.memory = input.nextInt();
227             pcbs.add(pcb);
228         }
229         System.out.println("请定义存储块数,并为他们分配区间:");
230         int m = input.nextInt();
231         ArrayList<Memorys> list = new ArrayList<Memorys>();
232         for (int i = 0; i < m; i++) {
233             Memorys nck = new Memorys();
234             System.out.println("请输入第" + (i + 1) + "个存储块的存储名和存储大小:");
235             nck.name = input.next();
236             nck.size = input.nextInt();
237             list.add(nck);
238         }
239         while (true) {
240             System.out.println("选择要采用的适配方法:");
241             System.out.println("  A:最先适应法");
242             System.out.println("  B:最佳适应法");
243             System.out.println("  C:最坏适应法");
244             String str = input.next();
245             Methid methid = new Methid();
246             if (str.equals("A")) {
247                 methid.swap(list);
248                 methid.print(list);
249                 Access access = new Access();
250                 access.mainMethid(str, pcbs, list);
251             } else if (str.equals("B")) {
252                 methid.print(list);
253                 Access access = new Access();
254                 access.mainMethid(str, pcbs, list);
255
256             } else if (str.equals("C")) {
257                 methid.print(list);
258                 Access access = new Access();
259                 access.mainMethid(str, pcbs, list);
260             }
261         }
262     }
263 }

实验结果如下:

  1 请输入进程数:
  2 3
  3 请输入第1个进程的名字/运行所占内存用空格隔开
  4 jincheng1 8
  5 请输入第2个进程的名字/运行所占内存用空格隔开
  6 jincheng2 4
  7 请输入第3个进程的名字/运行所占内存用空格隔开
  8 jincheng3 7
  9 请定义存储块数,并为他们分配区间:
 10 4
 11 请输入第1个存储块的存储名和存储大小:
 12 cuncu1 5
 13 请输入第2个存储块的存储名和存储大小:
 14 cuncu2 8
 15 请输入第3个存储块的存储名和存储大小:
 16 cuncu3 9
 17 请输入第4个存储块的存储名和存储大小:
 18 cuncu4 6
 19 选择要采用的适配方法:
 20   A:最先适应法
 21   B:最佳适应法
 22   C:最坏适应法
 23 A
 24 将存储块大小进行排序之后:
 25     存储块名    存储大小    存储状态
 26     cuncu1    5    空闲
 27     cuncu4    6    空闲
 28     cuncu2    8    空闲
 29     cuncu3    9    空闲
 30 请输入你要操作的步骤:
 31   1:运行进程  2:结束进程  3:结束当前算法
 32 请输入:1
 33 请输入当前要运行的进程名
 34 jincheng2
 35     存储块名    存储大小    存储状态
 36     cuncu1    4    jincheng2正在运行
 37     子存储块    1    空闲
 38     cuncu4    6    空闲
 39     cuncu2    8    空闲
 40     cuncu3    9    空闲
 41 请输入你要操作的步骤:
 42   1:运行进程  2:结束进程  3:结束当前算法
 43 请输入:1
 44 请输入当前要运行的进程名
 45 jincheng3
 46     存储块名    存储大小    存储状态
 47     cuncu1    4    jincheng2正在运行
 48     子存储块    1    空闲
 49     cuncu4    6    空闲
 50     cuncu2    7    jincheng3正在运行
 51     子存储块    1    空闲
 52     cuncu3    9    空闲
 53 请输入你要操作的步骤:
 54   1:运行进程  2:结束进程  3:结束当前算法
 55 请输入:1
 56 请输入当前要运行的进程名
 57 jincheng1
 58     存储块名    存储大小    存储状态
 59     cuncu1    4    jincheng2正在运行
 60     子存储块    1    空闲
 61     cuncu4    6    空闲
 62     cuncu2    7    jincheng3正在运行
 63     子存储块    1    空闲
 64     cuncu3    8    jincheng1正在运行
 65     子存储块    1    空闲
 66 请输入你要操作的步骤:
 67   1:运行进程  2:结束进程  3:结束当前算法
 68 请输入:2
 69 请输入要结束的进程名
 70 jincheng2
 71     存储块名    存储大小    存储状态
 72     cuncu1    4    空闲
 73     子存储块    1    空闲
 74     cuncu4    6    空闲
 75     cuncu2    7    jincheng3正在运行
 76     子存储块    1    空闲
 77     cuncu3    8    jincheng1正在运行
 78     子存储块    1    空闲
 79 请输入你要操作的步骤:
 80   1:运行进程  2:结束进程  3:结束当前算法
 81 请输入:2
 82 请输入要结束的进程名
 83 jincheng3
 84     存储块名    存储大小    存储状态
 85     cuncu1    4    空闲
 86     子存储块    1    空闲
 87     cuncu4    6    空闲
 88     cuncu2    7    空闲
 89     子存储块    1    空闲
 90     cuncu3    8    jincheng1正在运行
 91     子存储块    1    空闲
 92 请输入你要操作的步骤:
 93   1:运行进程  2:结束进程  3:结束当前算法
 94 请输入:2
 95 请输入要结束的进程名
 96 jincheng1
 97     存储块名    存储大小    存储状态
 98     cuncu1    4    空闲
 99     子存储块    1    空闲
100     cuncu4    6    空闲
101     cuncu2    7    空闲
102     子存储块    1    空闲
103     cuncu3    8    空闲
104     子存储块    1    空闲
105 请输入你要操作的步骤:
106   1:运行进程  2:结束进程  3:结束当前算法
107 请输入:3
108 请输入你要操作的步骤:
109   1:运行进程  2:结束进程  3:结束当前算法
110 请输入:
时间: 2024-10-18 15:11:19

存储器的分配与回收算法实现的相关文章

认识JVM(1)&mdash;&mdash;对象分配&amp;回收算法

本来标题党想写成<深入JVM>,不过不太敢写,我想一小篇博客我想还不足以说明JVM,在本文中,会就我所知给大家介绍JVM的很多内部知识,概念会相对较粗,因为太细的内容要写,这里肯定写不出来:本文主要偏重理论,没有什么实践,中间除一些官方资料外,还有部分自身的理解,所以请大家不要完全信任本文内容:另外本文会有一小部分纠正以前一篇文章对于intern()使用方法的错误,本文会在其中说明使用错误的原因,大致文章内容有以下几个部分: 1.JVM虚拟内存组成及操作系统地址表 2.新生成对象在HeapSi

Java GC 垃圾回收算法 内存分配

垃圾回收(Garbage Collection, GC)是Java不同于c与c++的重要特性之一. 他帮助Java自动清空堆中不再使用的对象. 由于不需要手动释放内存,程序员在编程中也可以减少犯错的机会. 利用垃圾回收,程序员可以避免一些指针和内存泄露相关的bug(这一类bug通常很隐蔽). 垃圾回收实际上是将原本属于程序员的责任转移给计算机. GC需要完成的3件事情: 哪些内存需要回收 什么时候回收 如何回收 1 回收那些对象? 在Java中采用可达性分析算法来判定对象是否存活,是否可以被回收

jvm内存模型-回收算法-和内存分配以及jdk、jre、jvm是什么关系(阿里,美团,京东面试题)

1.什么是jvm?(1)jvm是一种用于计算设备的规范,它是一个虚构出来的机器,是通过在实际的计算机上仿真模拟各种功能实现的.(2)jvm包含一套字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和一个存储方法域.(3)JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行.JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行. 2.jdk.jre.jvm是什么关系?(1)JRE(Java

JVM内存分配策略,及垃圾回收算法

本人免费整理了Java高级资料,一共30G,需要自己领取;传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q 说起垃圾收集(Garbage Collection, GC),想必大家都不陌生,它是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行在JVM上的语言,如Scala等)程序员在提升开发效率上获得了惊人的便利.理解GC,对于理解JVM和Java语言有着非常重要的作用.并且当我们需要排查各种内存溢

JVM虚拟机-03、JVM内存分配机制与垃圾回收算法

JVM虚拟机-03.JVM内存分配机制与垃圾回收算法 1 JVM内存分配与回收 1.1 对象优先在Eden区分配 大多数情况下,对象在新生代中?Eden?区分配.当?Eden?区没有足够空间进行分配时,虚拟机将发起一次Minor?GC.我们来进行实际测试一下.在测试之前我们先来看看?Minor?GC和Full?GC?有什么不同呢? Minor?GC/Young?GC:指发生新生代的的垃圾收集动作,MinorGC非常频繁,回收速度一般也比较快. Major?GC/Full?GC:一般会回收老年代,

模拟操作系统中进程的三种基础状态与内存的分配和回收(最佳适配算法)

利用键盘模拟进程的三种操作状态,并且使用C++中的list模板模拟内存的分配和回收. 能够模拟进程的创建与撤销过程 l可对进程的状态进行全面的控制 按先进先出方式管理就绪和阻塞队列,能够按队列形式输出进程状 用PCB代表进程,用全局变量表示进程的个数. 1 #include <iostream> 2 #include <list> 3 #include <numeric> 4 #include <algorithm> 5 #include<stdlib

jvm学习笔记一(垃圾回收算法)

一:垃圾回收机制的原因 java中,当没有对象引用指向原先分配给某个对象的内存时候,该内存就成为了垃圾.JVM的一个系统级线程会自动释放该内存块.垃圾回收意味着程序不再需要的对象是"无用信息",这些信息将被丢弃.当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用.事实上,除了释放没用的对象,垃圾回收也可以清除内存记录碎片.由于创建对象和垃圾回收器释放丢弃对象所占的内存空间,内存会出现碎片.碎片是分配给对象的内存块之间的空闲内存洞.碎片整理将所占用的堆内存移到堆

java----java垃圾回收算法

1.引用计数法(Reference Counting Collector) 1.1算法分析 引用计数是垃圾收集器中的早期策略.在这种方法中,堆中每个对象实例都有一个引用计数.当一个对象被创建时,且将该对象实例分配给一个变量,该变量计数设置为1.当任何其它变量被赋值为这个对象的引用时,计数加1(a = b,则b引用的对象实例的计数器+1),但当一个对象实例的某个引用超过了生命周期或者被设置为一个新值时,对象实例的引用计数器减1.任何引用计数器为0的对象实例可以被当作垃圾收集.当一个对象实例被垃圾收

垃圾回收算法(5)分代回收

分代垃圾回收,基于的是“大部分的对象,在生成后马上就会变成垃圾”这一经验上的事实为设计出发点.此前讨论过基于引事实的另一个垃圾回收算法,引用计数出的一些优化思路. 分代的关键是: 给对象记录下一个age,随着每一次垃圾回收,这个age会增加: 给不同age的对象分配不同的堆内内存空间,称为某一代: 对某一代的空间,有适合其的垃圾回收算法: 对每代进行不同垃圾回收,一般会需要一个额外的信息:即每代中对象被其他代中对象引用的信息.这个引用信息对于当前代来说,扮演与"root"一样的角色,也