1 概述
本文是利用Java
实现操作系统中的四种动态内存分配方式 ,分别是:
BF
NF
WF
FF
分两部分,第一部分是介绍四种分配方式的概念以及例子,第二部分是代码实现以及讲解。
2 四种分配方式
2.1 概念
操作系统中有一个动态分区分配的概念,内存在初始化的时候不会划分区域,而是在进程装入的时候,根据所要装入的进程动态地对内存空间进行划分,以提高内存空间的利用率,降低碎片的大小,主要的方法有一下四种:
- 首次适应算法(
First Fit
):从空闲分区链首开始查找,直到找到一个满足其大小要求的空闲分区为止 - 循环首次适应算法(
Next Fit
):从上次找到的空闲分区的下一个开始查找 - 最佳适应算法(
Best Fit
):把空闲分区按大小递增的方式形成分区链,找到第一个能满足要求的空闲分区就进行分配 - 最坏适应算法(
Worst Fit
):与最佳适应算法相反,把空闲分区按大小递减的方式形成分区链,找到第一个能满足要求的空闲分区就进行分配
2.2 例子
假设现在有100MB
的内存空间,某一时刻先后分配了20MB
、4MB
、10MB
内存,示意图如下:
现在需要再分配5MB
内存。
若采用FF
,因为FF
是直接按顺序分配内存,从低地址开始搜索空闲分区,因此便会从第一块空闲分区分配5MB
(地址0-5
),示意图:
若采用NF
,NF
与FF
类似,只不过NF
是从上一次找到的空闲分区的下一块开始查找,因为上一次分配的是10MB
,因此会从最后一块空闲分区(地址80-100
)分配内存:
若采用BF
,BF
是遍历所有空闲分区并找到一个能满足要求的最小分区,也就会找到一个比5MB
大的空闲分区,且该空闲分区是所有空闲分区中最小的,也就是地址为64-70
的空闲分区:
若采用WF
,WF
与BF
相反,总是从最大的空闲分区开始分配,因此会从地址为30-60
的空闲分区进行分配:
3 代码实现
3.1 总览
代码分成了四个类:
Main
:测试Print
:输出打印Table
:表示每一个分区TableList
:对分区进行控制,包括初始化,分配,回收等
3.2 Main
Main
是测试类,代码如下:
public class Main {
private final static TableList list = new TableList(64);
public static void main(String[] args) {
list.useWF();
// list.useBF();
// list.useNF();
// list.useFF();
list.allocate(10);
list.allocate(20);
list.free(10);
list.show();
list.allocate(8);
list.show();
list.allocate(13);
list.allocate(1);
list.show();
list.free(1);
list.allocate(9);
list.free(13);
list.show();
list.allocate(18);
list.show();
list.allocate(3);
list.allocate(4);
list.free(20);
list.free(8);
list.show();
list.allocate(8);
list.free(9);
list.show();
list.clear();
list.show();
}
}
通过TableList
对内存进行分配以及释放,初始化分配64MB
大小内存,切换分配算法时使用前四行的其中一行即可。
3.3 Table
Table
类表示每一个分区,无论是空闲的还是已分配的,成员变量有四个,分别是:
- 起始地址
- 大小
- 是否空闲(只有两种状态,空闲或分配)
- 是否是上一次分配(
NF
专用)
代码如下:
@AllArgsConstructor
public class Table {
@Getter
@Setter
private int address;
@Setter
@Getter
private int size;
private boolean free;
@Getter
@Setter
private boolean lastAllocated;
public static Table freeTable(int address,int size)
{
return new Table(address,size,true,false);
}
public static Table allocatedTable(int address,int size)
{
return new Table(address,size,false,false);
}
public boolean isFree()
{
return free;
}
public boolean isAllocated()
{
return !isFree();
}
public void setFree()
{
free = true;
}
}
只有一些Getter
和Setter
,为了方便提供了一个创建空闲分区或已分配分区的静态方法,指定起始地址和大小即可。
3.4 TableList
TableList
是整个算法的核心类,成员变量如下:
private final List<Table> list = new ArrayList