固定分区分配是最简单的一种多道程序存储管理方式,它将用户内存空间划分为若干个固定大小的区域,每个分区只装入一道作业。当有空闲分区时,便可以再从外存的后背作业队列中,选择适当大小的作业装入该分区,如此循环。
分区大小相等:用于利用一台计算机控制多个相同对象的场合,缺乏灵活性
分区大小不等:划分为含有多个较小的分区,适量的中等分区及少量的大分区。
优点:1.没有外部碎片
缺点:1.程序可能太大而放不进任何一个分区中,这时用户不得不使用覆盖技术来使用内存空间。
主存利用率低,当程序小于固定分区大小时,也占用一个完整的内存分区空间,这样分区内部有空间浪费,这种现象称为内部碎片。
不能多个进程共享一个主存区
package com.qiu;
import java.util.Collections;
import java.util.Date;
public class mem_a extends Thread{
public char[] mem;
//定义内存大小
public mem_a(int size) {
mem=new char[size];
for(int i=0;i<size;i++) {
mem[i]='_';
}
}
@Override
public void run() {
while(true) {
try {
/**Collections工具类中的nCopies(int n,T o)方法用于返回一个不可变列表组成的n个拷贝的指定对象。
* 此处即是将"/n"拷贝100次并以字符串形式放回(模拟内存的读写过程中间的页面刷新)
* */
System.out.println(Collections.nCopies(100, "\n").stream().reduce((a, b)->a+b).get());
//s1为模拟内存逻辑地址,初始状态还未分配资源全为‘_’
StringBuffer s1=new StringBuffer("[");
for(int i=0;i<mem.length;i++) {
s1.append(mem[i]);
}
s1.append("]");
//s2模拟内存分区大小
StringBuffer s2=new StringBuffer("[1");
for(int i=1;i<mem.length-1;i++) {
s2.append('_');
if(mem[i]!=mem[i+1]&&i!=0) {
s2.append(i+1);
i+=(i+"").length();
}
}
s2.append(mem.length+"]");
System.out.println(new Date());
System.out.println(s1);
System.out.println(s2);
Thread.sleep(100);
}catch(Exception e) {
e.printStackTrace();
}
}
}
//分配内存方法
public void allocate(char key,int start,int length) {
for(int i=start;i<start+length;i++) {
mem[i]=key;
}
}
//释放内存方法
public void free(char key) {
for(int i=0;i<mem.length;i++) {
if(mem[i]==key) {
mem[i]='_';
}
}
}
public static void main(String[] args) throws InterruptedException {
mem_a m=new mem_a(100);
m.start();
Thread.sleep(3000);
m.allocate('a', 0, 30);
Thread.sleep(3000);
m.allocate('b', 40, 20);
Thread.sleep(3000);
m.allocate('a', 80, 20);
Thread.sleep(3000);
m.free('b');
}
}
动态分区分配又称为可变分区分配。这种分配方式不会预先划分内存分区,而是在进程装入内存时,根据进程的大小动态地建立分区,并使分区的大小正好适合进程的需要。因此系统分区的大小和数目是可变的。
算法思想:每次都从低地址开始查找,找到第–个能满足大小的空闲分区。
如何实现:空闲分区以地址递增的次序排列。每次分配内存时顺序查找空闲分区链( 或空闲分[表),找到大小能满足要求的第-一个空闲分区。
package com.qiu;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
public class mem_b extends Thread{
public char[] mem;
//定义内存大小
public mem_b(int size) {
mem=new char[size];
for(int i=0;i<size;i++) {
mem[i]='_';
}
}
@Override
public void run() {
while(true) {
try {
/**Collections工具类中的nCopies(int n,T o)方法用于返回一个不可变列表组成的n个拷贝的指定对象。
* 此处即是将"/n"拷贝100次并以字符串形式放回(模拟内存的读写过程中间的页面刷新)
* */
System.out.println(Collections.nCopies(100, "\n").stream().reduce((a, b)->a+b).get());
//s1为模拟内存逻辑地址,初始状态还未分配资源全为‘_’
StringBuffer s1=new StringBuffer("[");
for(int i=0;i<mem.length;i++) {
s1.append(mem[i]);
}
s1.append("]");
//s2模拟内存分区大小
StringBuffer s2=new StringBuffer("[1");
for(int i=1;i<mem.length-1;i++) {
s2.append('_');
if(mem[i]!=mem[i+1]&&i!=0) {
s2.append(i+1);
i+=(i+"").length();
}
}
s2.append(mem.length+"]");
System.out.println(new Date());
System.out.println(s1);
System.out.println(s2);
Thread.sleep(100);
}catch(Exception e) {
e.printStackTrace();
}
}
}
int lastpos=0;
LinkedList<Character> waitkey=new LinkedList<>();
LinkedList<Integer> waitSize=new LinkedList<>();
public boolean allocate(char key,int size) {
int freemem=0,begin=lastpos;
boolean quit=false;
while(true) {
if(mem[lastpos]=='_') {
freemem++;
if(freemem==size) {
lastpos++;
for(int i=0;i<size;i++) {
mem[(i+lastpos-size+mem.length)%mem.length]=key;
}
return true;
}
}else {
freemem=0;
if(quit) {
break;
}
}
lastpos=(++lastpos)%mem.length;
if(lastpos==begin) {
quit=true;
}
}
waitkey.push(key);
waitSize.push(size);
return false;
}
public void free(char key) {
for(int i=0;i<mem.length;i++) {
if(mem[i]==key) {
mem[i]='_';
}
}
int waitnum=waitkey.size();
for(int i=0;i<waitnum;i++) {
allocate(waitkey.poll(),waitSize.poll());
}
}
public static void main(String[] args) throws InterruptedException {
mem_b m=new mem_b(100);
m.start();
Thread.sleep(3000);
m.allocate('a', 30);
Thread.sleep(3000);
m.allocate('b', 40);
Thread.sleep(3000);
m.allocate('c', 50);
Thread.sleep(3000);
m.allocate('d', 20);
Thread.sleep(3000);
m.free('a');
Thread.sleep(3000);
m.free('d');
}
}
算法思想:由于动态分区分配是一种连续分配方式,为各进程分配的空间必须是连续的一整片区域。因此为了保证当“大进程”到来时能有连续的大片空间,可以尽可能多地留下大片的空闲区,即,优先使用更小的空闲区。
如何实现:空闲分区按容量递增次序链接。每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能满足要求的第-一个空闲分区。
java实现:
package com.qiu;
import javafx.util.Pair;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedList;
public class mem_c extends Thread{
public char[] mem;
//定义内存大小
public mem_c(int size) {
mem=new char[size];
for(int i=0;i<size;i++) {
mem[i]='_';
}
}
@Override
public void run() {
while(true) {
try {
/**Collections工具类中的nCopies(int n,T o)方法用于返回一个不可变列表组成的n个拷贝的指定对象。
* 此处即是将"/n"拷贝100次并以字符串形式放回(模拟内存的读写过程中间的页面刷新)
* */
System.out.println(Collections.nCopies(100, "\n").stream().reduce((a, b)->a+b).get());
//s1为模拟内存逻辑地址,初始状态还未分配资源全为‘_’
StringBuffer s1=new StringBuffer("[");
for(int i=0;i<mem.length;i++) {
s1.append(mem[i]);
}
s1.append("]");
//s2模拟内存分区大小
StringBuffer s2=new StringBuffer("[1");
for(int i=1;i<mem.length-1;i++) {
s2.append('_');
if(mem[i]!=mem[i+1]&&i!=0) {
s2.append(i+1);
i+=(i+"").length();
}
}
s2.append(mem.length+"]");
System.out.println(new Date());
System.out.println(s1);
System.out.println(s2);
Thread.sleep(100);
}catch(Exception e) {
e.printStackTrace();
}
}
}
LinkedList<Character> waitkey=new LinkedList<>();
LinkedList<Integer> waitSize=new LinkedList<>();
/*
* java Pair类的使用场景:
* 当我们在写一个方法需要返回两个字段值时,我之前的方法是新建一个类或使用集合。目前来看使用Pair方便很多。
配对(Pair)。配对提供了一种方便方式来处理简单的键值关联,当我们想从方法返回两个值时特别有用。
*/
LinkedList<Pair<Integer,Integer>> size_start=new LinkedList<>();
public void updateFreeList() {
size_start.clear();
int freecount=0;
for(int i=0;i<mem.length;i++) {
if(mem[i]=='_') {
freecount++;
}else {
if(freecount>0) {
size_start.add(new Pair<Integer,Integer>(freecount,i-freecount));
freecount=0;
}
}
}
if(freecount>0) {
size_start.add(new Pair<Integer,Integer>(freecount,mem.length-freecount));
freecount=0;
}
Collections.sort(size_start,new Comparator<Pair<Integer,Integer>>(){
public int compare(Pair<Integer,Integer> o1,Pair<Integer,Integer> o2) {
return o1.getKey()-o2.getKey();
};
});
}
public boolean allocate(char key,int size) {
updateFreeList();
boolean quit=false;
for(Pair<Integer,Integer> entry:size_start) {
if(entry.getKey()>=size) {
for(int i=0;i<size;i++) {
mem[entry.getValue()+i]=key;
}
updateFreeList();
quit=true;
break;
}
}
if(!quit) {
waitkey.push(key);
waitSize.push(size);
}
return quit;
}
public void free(char key) {
for(int i=0;i<mem.length;i++) {
if(mem[i]==key) {
mem[i]='_';
}
}
int waitnum=waitkey.size();
for(int i=0;i<waitnum;i++) {
allocate(waitkey.poll(),waitSize.poll());
}
}
public static void main(String[] args) throws InterruptedException {
mem_c m=new mem_c(100);
m.start();
Thread.sleep(3000);
m.allocate('a', 30);
Thread.sleep(3000);
m.allocate('b', 40);
Thread.sleep(3000);
m.allocate('c', 50);
Thread.sleep(3000);
m.allocate('d', 20);
Thread.sleep(3000);
m.free('a');
Thread.sleep(3000);
m.free('d');
Thread.sleep(3000);
m.allocate('e', 30);
}
}
原因:Pair类 javafx.util.Pair无法找到
解决方法:
window->Perferences
之后再次运行,便ok了