CloudSim源碼分析之主機資源分配(內存篇)

      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;
	}


}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章