RamProvisionerSimple類和PeProvisionerSimple類比較類似,也是定義一個可用內存,每爲一臺虛擬機成功分配內存後,可用內存就相應的減少,當可用內存低於要分配的值時,分配就會失敗。不同的是,如果爲已分配的虛擬機再次分配內存,需要先釋放內存,然後再進行分配。內存分配策略是初始化Host對象時指定的,由Host類的構造函數傳入。詳細源代碼如下:
/*
* Title: CloudSim Toolkit
* Description: CloudSim (Cloud Simulation) Toolkit for Modeling and Simulation of Clouds
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2009-2010, The University of Melbourne, Australia
*/
package org.cloudbus.cloudsim.provisioners;
import java.util.HashMap;
import java.util.Map;
import org.cloudbus.cloudsim.Vm;
/**
* RamProvisionerSimple is an extension of RamProvisioner
* which uses a best-effort policy to allocate memory to a VM.
*
* @author Rodrigo N. Calheiros
* @author Anton Beloglazov
* @since CloudSim Toolkit 1.0
*/
public class RamProvisionerSimple extends RamProvisioner {
/** The RAM table. */
//保存虛擬機ID和分配的內存大小之間的映射
private Map<String, Integer> ramTable;
/**
* Instantiates a new ram provisioner simple.
*
* @param availableRam the available ram
*/
public RamProvisionerSimple(int availableRam) {
//初始化可用內存大小和ramTable
super(availableRam);
setRamTable(new HashMap<String, Integer>());
}
/* (non-Javadoc)
* @see cloudsim.provisioners.RamProvisioner#allocateRamForVm(cloudsim.Vm, int)
*/
@Override
public boolean allocateRamForVm(Vm vm, int ram) {
//獲得初始化虛擬機時指定的內存大小
int maxRam = vm.getRam();
//如果申請分配的內存超過maxRam,無需分配多餘的內存給虛擬機
if (ram >= maxRam) {
ram = maxRam;
}
//釋放以前分配的內存
deallocateRamForVm(vm);
//如果可用內存不小於申請的內存,即可進行分配
if (getAvailableRam() >= ram) {
setAvailableRam(getAvailableRam() - ram);
getRamTable().put(vm.getUid(), ram);
//更新虛擬機當前已分配的內存大小
vm.setCurrentAllocatedRam(getAllocatedRamForVm(vm));
return true;
}
//如果失敗,虛擬機當前分配的內存大小理應變爲0,那麼下面這句有用嗎?
vm.setCurrentAllocatedRam(getAllocatedRamForVm(vm));
return false;
}
/* (non-Javadoc)
* @see cloudsim.provisioners.RamProvisioner#getAllocatedRamForVm(cloudsim.Vm)
*/
@Override
public int getAllocatedRamForVm(Vm vm) {
if (getRamTable().containsKey(vm.getUid())) {
return getRamTable().get(vm.getUid());
}
return 0;
}
/* (non-Javadoc)
* @see cloudsim.provisioners.RamProvisioner#deallocateRamForVm(cloudsim.Vm)
*/
@Override
public void deallocateRamForVm(Vm vm) {
if (getRamTable().containsKey(vm.getUid())) {
//刪除已爲虛擬機分配的內存,可用內存大小增加相應的大小
int amountFreed = getRamTable().remove(vm.getUid());
setAvailableRam(getAvailableRam() + amountFreed);
//更新虛擬機當前分配的內存爲0
vm.setCurrentAllocatedRam(0);
}
}
/* (non-Javadoc)
* @see cloudsim.provisioners.RamProvisioner#deallocateRamForVm(cloudsim.Vm)
*/
@Override
public void deallocateRamForAllVms() {
//釋放所有內存,實際上就是調用父類方法將可用內存重置爲初始值,並清空ramTable
super.deallocateRamForAllVms();
getRamTable().clear();
}
/* (non-Javadoc)
* @see cloudsim.provisioners.RamProvisioner#isSuitableForVm(cloudsim.Vm, int)
*/
//該方法通過調用allocateRamForVm方法判斷,爲指定虛擬機分配指定大小的內存是否會成功
@Override
public boolean isSuitableForVm(Vm vm, int ram) {
//調用allocateRamForVm前保存當前的分配,用於後面恢復到當前狀態
int allocatedRam = getAllocatedRamForVm(vm);
//嘗試爲指定虛擬機分配指定大小的內存
boolean result = allocateRamForVm(vm, ram);
//恢復到嘗試前的狀態
deallocateRamForVm(vm);
if (allocatedRam > 0) {
allocateRamForVm(vm, allocatedRam);
}
return result;
}
/**
* Gets the ram table.
*
* @return the ram table
*/
protected Map<String, Integer> getRamTable() {
return ramTable;
}
/**
* Sets the ram table.
*
* @param ramTable the ram table
*/
protected void setRamTable(Map<String, Integer> ramTable) {
this.ramTable = ramTable;
}
}