1. 程式人生 > >記憶體分配(首次適應演算法)

記憶體分配(首次適應演算法)

首次適應演算法

  使用該演算法進行記憶體分配時,從空閒分割槽鏈首開始查詢,直至找到一個能滿足其大小需求的空閒分割槽為止;然後再按照作業的大小,從該分割槽中劃出一塊記憶體分配給請求者,餘下的空閒分割槽仍留在空閒分割槽鏈中。

  該演算法傾向於使用記憶體中低地址部分的空閒分割槽,在高地址部分的空閒分割槽非常少被利用,從而保留了高地址部分的大空閒區。顯然為以後到達的大作業分配大的記憶體空間創造了條件。缺點在於低址部分不斷被劃分,留下許多難以利用、非常小的空閒區,而每次查詢又都從低址部分開始,這無疑會增加查詢的開銷。

  首次適應演算法的具體程式碼實現:

  資料結構:我們將計算機的記憶體地址抽象為一個連結串列,連結串列的節點包括首地址、記憶體大小、和當前的狀態(是否被使用)。

每程序則用程序類例項化的物件來表示;程序中的屬性有程序名以及程序所需記憶體的大小;

 具體程式碼實現:

程序類:

public class Process {
	String pName;   //作業號
	int pSize;      //作業大小
	public String getpName() {
		return pName;
	}
	public void setpName(String pName) {
		this.pName = pName;
	}
	public int getpSize() {
		return pSize;
	}
	public void setpSize(int pSize) {
		this.pSize = pSize;
	}

}
演算法介面類:
public interface DynamicStoreAlgorithm {
	 void init(int size);   //初始化分割槽連結串列
	 boolean allocatePartition(Process process);  //分配分割槽
	 boolean recoverPartition(Process process);   //回收分割槽
	 void unitPartition(MNode mnode);  //合併空閒分割槽
	 void show(); //顯示當前的記憶體狀態	
}

介面實現類:
public class DynamicStoreAlgorithmImpl implements DynamicStoreAlgorithm{
	
	private MNode mHeadNode;
	
	public DynamicStoreAlgorithmImpl(){
		mHeadNode = new MNode();
	}
	
	@Override
	public boolean allocatePartition(Process process) {
		// TODO Auto-generated method stub
		boolean flag = false;
		MNode Node = mHeadNode;
		while(Node.getNextNode() != null){
			Node = Node.getNextNode();
			if(Node.getSize()>process.getpSize()){  //當程序所需的大小小於空閒記憶體分割槽時;
				flag = true;
				//申請新的記憶體空間,並進行初始化
				MNode mNode = new MNode();
				mNode.setSize(process.getpSize());
				mNode.setStartIndex(Node.getStartIndex());
				mNode.setFree(false);
				mNode.setProcessName(process.getpName());
				
				//修改原來結點的資料結構
				Node.setSize(Node.getSize()-process.getpSize());
				Node.setStartIndex(Node.getStartIndex()+process.getpSize());
				
				//改變當前連結串列指標的指向
				MNode m = Node.getPreNode();
				mNode.setPreNode(m);
				Node.getPreNode().setNextNode(mNode);
				Node.setPreNode(mNode);
				mNode.setNextNode(Node);
				break;
			}else if(Node.getSize()== process.getpSize()){
				flag = true;
				Node.setProcessName(process.getpName());
				Node.setFree(false);
				break;
			}
			
		}
		//若flag為真,則找到分割槽分配給程序;若為假則沒有適當的空閒分割槽可以分配給該程序
		if(flag){
			return true;
		}
		else
			return false;
	}

	@Override
	public void init(int size) {
		// TODO Auto-generated method stub	
		MNode mNode = new MNode();
		mNode.setNextNode(null);
		mNode.setPreNode(mHeadNode);
		mNode.setStartIndex(0);
		mNode.setSize(size);
		mNode.setFree(true);
		
		mHeadNode.setPreNode(null);
		mHeadNode.setNextNode(mNode);
		
	}

	@Override
	public boolean recoverPartition(Process process) {
		// TODO Auto-generated method stub
		boolean flag = false;
		MNode node = mHeadNode;
		while(node.getNextNode()!= null){
			node = node.getNextNode();
			if(node.getProcessName()!=null && node.getProcessName().equals(process.getpName())){
				node.setFree(true);
				node.setProcessName(null);
				unitPartition(node);
				flag=true;
				break;
			}
		}
		return flag;
	}

	@Override
	public void unitPartition(MNode mnode) {
		// TODO Auto-generated method stub
		MNode preNode = mnode.getPreNode();
		MNode nextNode = mnode.getNextNode();
		
		if(preNode.isFree()&&nextNode.isFree()){
			int size = preNode.getSize()+mnode.getSize()+nextNode.getSize();
			preNode.setSize(size);
			preNode.setNextNode(nextNode.getNextNode());
		}else if(!preNode.isFree() && nextNode.isFree()){
			int size = mnode.getSize()+nextNode.getSize();
			mnode.setSize(size);
			mnode.setNextNode(nextNode.getNextNode());
		}else if(preNode.isFree() && !nextNode.isFree()){
			int size = preNode.getSize()+mnode.getSize();
			preNode.setSize(size);
			preNode.setNextNode(nextNode);
		}
	}

	@Override
	public void show() {
		// TODO Auto-generated method stub
		MNode node = mHeadNode;
		System.out.println("分割槽號"+"\t"+"開始地址"+"\t"+"分割槽大小"+"\t"+"狀態(t空 f忙)"+"\t"+"執行程序");
		int i=1;
		while(node.getNextNode()!= null){
			node = node.getNextNode();
			System.out.println(i+"\t"+node.getStartIndex()+"\t"+node.getSize()+"\t"+node.isFree()+"\t\t"+node.getProcessName());
			i++;
		}
	}
	
}

結點類:
package hwchao.algorithm;

public class MNode {
	private String processName; //正在使用的程序號
	private MNode preNode;      //前驅結點
	private MNode nextNode;		//後繼結點
	private int startIndex;		//開始地址
	private boolean free;		//分割槽狀態 1.true表示空閒 2.false表示使用
	private int size;           //分割槽大小
	
	public String getProcessName() {
		return processName;
	}
	public void setProcessName(String processName) {
		this.processName = processName;
	}
	public MNode getPreNode() {
		return preNode;
	}
	public void setPreNode(MNode preNode) {
		this.preNode = preNode;
	}
	public MNode getNextNode() {
		return nextNode;
	}
	public void setNextNode(MNode nextNode) {
		this.nextNode = nextNode;
	}
	public int getStartIndex() {
		return startIndex;
	}
	public void setStartIndex(int startIndex) {
		this.startIndex = startIndex;
	}

	public boolean isFree() {
		return free;
	}
	public void setFree(boolean free) {
		this.free = free;
	}
	public int getSize() {
		return size;
	}
	public void setSize(int size) {
		this.size = size;
	}
	
	
}

主方法:
import java.util.Scanner;
import hwchao.algorithm.Process;

import hwchao.algorithm.DynamicStoreAlgorithmImpl;

public class Main {
	static Scanner input = new Scanner(System.in);
	public static void main(String[] args){
		DynamicStoreAlgorithmImpl dsa = new DynamicStoreAlgorithmImpl();
		dsa.init(1024);
		String operation=null;
		System.out.println("'add'新增程序 'delete'刪除程序 'view'檢視記憶體當前狀態 'end'結束程式");
		do{
			operation = input.next();
			if("add".equals(operation)){
				System.out.println("請輸入要新增的程序名和所需的記憶體大小。");
				Process process = new Process();
				String name = input.next();
				int size = input.nextInt();
				process.setpName(name);
				process.setpSize(size);
				dsa.allocatePartition(process);
				System.out.println("程序正在執行...");
			}else if("delete".equals(operation)){
				System.out.println("請輸入要刪除的程序名。");
				Process process = new Process();
				String name = input.next();
				process.setpName(name);
				if(dsa.recoverPartition(process)){
					System.out.println("程序已撤銷...");
				}else{
					System.out.println("程序不存在...");
				}
			}else if("view".equals(operation)){
				System.out.println("當前的記憶體狀態");
				dsa.show();
			}
			
		}while(!("end").equals(operation));
		
	}
}



相關推薦

記憶體分配首次適應演算法

首次適應演算法:   使用該演算法進行記憶體分配時,從空閒分割槽鏈首開始查詢,直至找到一個能滿足其大小需求的空閒分割槽為止;然後再按照作業的大小,從該分割槽中劃出一塊記憶體分配給請求者,餘下的空閒分割槽仍留在空閒分割槽鏈中。   該演算法傾向於使用記憶體中低地址部分的空閒分

系統記憶體分配首次適應演算法和最佳適應演算法連結串列模擬實現

#include<iostream> #include<stdlib.h> using namespace std; #define Free 0 //空閒狀態 #define Busy 1 //已用狀態 #define OK 1    //完成

c模擬記憶體分配演算法首次適應演算法,最佳適應演算法,最壞適應演算法

#include<bits/stdc++.h> using namespace std; /*定義記憶體的大小為100*/ #define MEMSIZE 100 /*如果小於此值,將不再分割記憶體*/ #define MINSIZE 2 /*記憶體分割槽空間表結構*/ typedef str

計算機作業系統 ----記憶體空間回收首次適應演算法和最佳適應演算法

#include<iostream.h>  #include<stdlib.h>  #define Free 0 //空閒狀態  #define Busy 1 //已用狀態  #define OK 1    //完成  #define ERROR 0

作業系統實驗報告---主存分配與回收最佳適應演算法

   動態分割槽主存的分配與回收                                                                      16網路工程二班 孫書魁目的:           1,瞭解動態分割槽分配中,使用的資料結構和演算法  

java 陣列實現動態的記憶體分配繼承的應用

如何實現動態分配? 說白了其實就是陣列大小由外部輸入,然後在動態生成陣列。 因此在新增元素時需要判斷陣列是否已經滿員了,所以類中需要一個記錄了陣列大小的標記,這裡記為font 我以下的程式碼寫了一個Array的父類和兩個繼承自它的子類SortArray可以實現陣

iOS開發中的記憶體分配堆和棧

程序的記憶體分割槽 所有程序(執行的程式)都必須佔用一定數量的記憶體,它或是用來存放從磁碟載入的程式程式碼,或是存放取自使用者輸入的資料等等。不過程序對這些記憶體的管理方式因記憶體用途不一而不盡相同,有些記憶體是事先靜態分配和統一回收的,而有些卻是按需要動態分配和回收的

記憶體分配malloc()和free()

C語言的一個特性是接近底層,對於硬體的控制能力比其他高階動態語言要強。同時,C語言賦予程式設計師更大的自由度,更信任程式設計師。在記憶體的分配與釋放上,我們知道非靜態變數(塊作用域,無連結,自動生存期)在程式進入到變數定義所在的地方(塊或函式內)時分配記憶體,在離開塊作用域時釋放。對於靜態變數,在程式載入到記

動態分割槽分配-迴圈首次適應演算法+最佳適應演算法

(文章待更新) (1)採用空閒區表,並增加已分配區表{未分配區說明表、已分配區說明表(分割槽號、起始地址、長度、狀態)}。分配演算法採用最佳適應演算法(記憶體空閒區按照尺寸大小從小到大的排列)和迴圈首次適應演算法,實現記憶體的分配與回收。 #include<iostr

首次適應演算法和最佳適應演算法指標模擬分配過程

實現程式記憶體的動態分配 首次適應演算法: 找到第一個滿足程式的記憶體塊,並將其分配給程式 最佳適應演算法: 找到所有的滿足程式的記憶體塊,並將其中最小的記憶體塊分配給程式 #include <iostream> #include <stri

作業系統可變分割槽用C語言實現按首次適應演算法分配記憶體

每個分割槽有4個數據項,起始地址,大小,狀態,程序號,其實地址和大小以KB為單位,狀態分為“已分”或“空閒”,程序號:若分割槽是已分,則填上此分割槽的程序號,若分割槽是空閒,則填入? 這裡先採用首次適應演算法,首次適應演算法是將空閒區按起始地址從小到大排序後,

Hadoop/Yarn/MapReduce記憶體分配配置方案

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

程式或-記憶體區域分配五個段

一. 在學習之前我們先看看ELF檔案。 ELF分為三種類型:.o 可重定位檔案(relocalble file),可執行檔案以及共享庫(shared library),三種格式基本上從結構上是一樣的,只是具體到每一個結構不同。下面我們就從整體上看看這3種格式從檔案內容上儲存的方式,spec上

儲存器管理——記憶體分配分割槽,段,頁

儲存器管理 連續分割槽兩種方式對比 固定分割槽 可變分割槽 分割槽記憶體大小 固定 可變 記憶體利用率 低 提高

類和動態記憶體分配3

定位new運算子號 //main.cpp #include<iostream> #include<string> using namespace std; const int BUF = 512; class JustTest { private: stri

類和動態記憶體分配2

·## 改進後的StringBad類: //stringbad.h #include <iostream> #ifndef STRINGBAD_H_ #define STRINGBAD_H_ class StringBad { private : char *str;

類和動態記憶體分配1

假設我們要建立一個類,其中有一個成員表示某人的姓,最簡單的就是用字串陣列來儲存,開始使用14個字元的陣列,發現太小,保險的方法是使用40個字元的陣列,但是當建立2000多個這個樣的物件時,必定會造成記憶體浪費。通常使用string類,該類有良好的記憶體管理細節。但是這樣就沒有機會深入的學習記

類和動態記憶體分配C++

動態記憶體和類: C++使用new和delete運算子來動態控制記憶體。C++在分配記憶體時採取的是:讓程式在執行時決定記憶體分配,而不是在編譯時決定。 首先,我們先構造一個只有字串、字串長度和字串個數的類: #pragma once #include<i

JVM heap記憶體分配1

隨筆。記錄各型別在堆記憶體中佔用記憶體空間大小的理解: 引用型別在堆中佔用4位元組, byte,boolean基本型別在堆中佔用1位元組, char,short基本型別在堆中佔用2位元組, int,float基本型別在堆中佔用4位元組, long,double基本型

C語言程式設計 學習筆記 動態記憶體分配malloc

如果輸入程式時,先告訴你個數,然後再輸入,要記錄每個資料(類似動態陣列) C99之前應該怎麼做呢? malloc()函式的作用就在此: int *a = (int*)malloc(n*sizeof(int)); malloc()函式的作用是向記憶體申請一個n*