操作系統|| 虛擬內存頁置換算法

題目

寫一個程序來實現 FIFO 和 LRU 頁置換算法。首先,產生一個隨機的頁面引用序列,頁面數從 0~9。將這個序列應用到每個算法并記錄發生的頁錯誤的次數。實現這個算法時要將頁幀的數量設為可變。假設使用請求調頁。可以參考所示的抽象類。

抽象類:

public abstract class ReplacementAlgorithm 
{ 
protected int pageFaultCount; // the number of page faults 
protected int pageFrameCount; // the number of physical page frame 
// pageFrameCount the number of physical page frames 
public ReplacementAlgorithm(int pageFrameCount) { 
if (pageFrameCount <0) 
throw new IllegalArgumentException(); 
this.pageFrameCount = pageFrameCount; 
pageFaultCount= 0; } 
// return - the number of page faults that occurred 
public int getPageFaultCount() { 
return pageFaultCount; 
} 
// int pageNumber - the page number to be inserted 
public abstract void insert (int pageNumber); 
} 


采用 LRU 頁置換算法,另一個采用 FIFO 算法。
有兩個類可以在線測試你的算法。
(1)PageGenerator——該類生成頁面引用序列,頁面數從 0~9。引用序列
的大小可作為 PageGenerateor 構造函數的參數。在創建 PageGenerator 對象后,
可用方法 getReferenceString0 方法返回作為引用序列的整數數組。
(2)Test-用來測試你的基于 ReplacementAlgorithm 的兩個類 FIFO 與 LRU。
Test 可按如下方法調用:

Java Test <reference string #> <# of page frames>?

算法介紹

先進先出算法(FIFO):缺頁中斷發生時,系統選擇在內存中駐留時間最長的頁面淘汰。通常采用鏈表記錄進入物理內存中的邏輯頁面,鏈首時間最長。
該算法實現簡單,但性能較差,調出的頁面可能是經常訪問的頁面,而且進程分配物理頁面數增加時,缺頁并不一定減少(Belady 現象)。

優點 :實現簡單,只需要維護一個先進先出隊列,每次淘汰時直接操作隊列頭部即可。
缺點 :性能較差,因為被調出的頁面可能是經常訪問的頁面。會發生 Belady 現象(顛簸現象),當進程分配的物理頁面數增加時,缺頁次數反而可能增加。

Java偽代碼:

public class FIFO {private Queue<Integer> queue = new LinkedList<>();private Set<Integer> pageSet = new HashSet<>();private int capacity;public FIFO(int capacity) {this.capacity = capacity;}public void accessPage(int page) {if (pageSet.contains(page)) {// 頁面已在內存中,不需要處理return;}if (pageSet.size() < capacity) {// 內存未滿,將頁面加入隊列和集合queue.offer(page);pageSet.add(page);System.out.println("頁面 " + page + " 調入內存");} else {// 內存已滿,淘汰隊首頁面int evictPage = queue.poll();pageSet.remove(evictPage);System.out.println("頁面 " + evictPage + " 被淘汰");// 將新頁面加入隊列和集合queue.offer(page);pageSet.add(page);System.out.println("頁面 " + page + " 調入內存");}}public static void main(String[] args) {FIFO fifo = new FIFO(3);int[] pages = {1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5};for (int page : pages) {System.out.print("訪問頁面 " + page + ":");fifo.accessPage(page);System.out.println("當前內存中的頁面:" + fifo.pageSet);System.out.println();}}
}


最近最久未使用算法(LRU):算法思想是缺頁發生時,選擇最長時間沒有被引用的頁面進行置換,如某些頁面長時間未被訪問,則它們在將來還可能會長時間不會訪問。該算法的開銷較大。

優點 :具有較好的性能,能夠較好地預測頁面的使用頻率。
缺點 :實現相對復雜,需要記錄每個頁面的訪問時間,并且每次訪問都需要更新訪問時間。

Java偽代碼:

public class LRU {private Map<Integer, Integer> pageMap = new HashMap<>();private List<Integer> pageList = new ArrayList<>();private int capacity;public LRU(int capacity) {this.capacity = capacity;}public void accessPage(int page) {if (pageMap.containsKey(page)) {// 頁面已在內存中,更新其位置pageList.remove(Integer.valueOf(page));pageList.add(page);System.out.println("頁面 " + page + " 已在內存中,更新其位置");} else {if (pageList.size() < capacity) {// 內存未滿,將頁面加入列表和映射pageList.add(page);pageMap.put(page, pageList.size() - 1);System.out.println("頁面 " + page + " 調入內存");} else {// 內存已滿,淘汰最久未使用的頁面(列表開頭的頁面)int evictPage = pageList.remove(0);pageMap.remove(evictPage);System.out.println("頁面 " + evictPage + " 被淘汰");// 將新頁面加入列表和映射pageList.add(page);pageMap.put(page, pageList.size() - 1);System.out.println("頁面 " + page + " 調入內存");}}}public static void main(String[] args) {LRU lru = new LRU(3);int[] pages = {1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5};for (int page : pages) {System.out.print("訪問頁面 " + page + ":");lru.accessPage(page);System.out.println("當前內存中的頁面:" + lru.pageList);System.out.println();}}
}

關鍵步驟

?(1)在PageGenerator類中,構造函數PageGenerator(int count)中生成隨機的頁面引用序列。

public PageGenerator(int count) {if (count < 0)throw new IllegalArgumentException();java.util.Random generator = new java.util.Random();referenceString = new int[count];for (int i = 0; i < count; i++)referenceString[i] = generator.nextInt(RANGE + 1);
}

(2)在ReplacementAlgorithm抽象類的子類FIFO和LRU中,實現頁面置換算法。
FIFO類:實現FIFO算法(First-In, First-Out):將最早插入的頁面替換出去。

@Override
public void insert(int pageNumber) {boolean pageFault = true;// 檢查頁面是否已經在物理頁面幀中for (int i = 0; i < pageFrameCount; i++) {if (pageFrames[i] == pageNumber) {pageFault = false;break;}}// 如果頁面不在物理頁面幀中,則發生頁面錯誤if (pageFault) {pageFaultCount++;pageFrames[currentIndex] = pageNumber;currentIndex = (currentIndex + 1) % pageFrameCount;}
}

LRU類:實現LRU算法(Least Recently Used):將最長時間未被使用的頁面替換出去

@Override
public void insert(int pageNumber) {boolean pageFault = true;int oldestTimestampIndex = 0;int oldestTimestamp = timestamps[0];// 檢查頁面是否已經在物理頁面幀中for (int i = 0; i < pageFrameCount; i++) {if (pageFrames[i] == pageNumber) {pageFault = false;// 更新頁面的時間戳timestamps[i] = getCurrentTimestamp();break;}// 找到最老的時間戳和對應的頁面幀索引if (timestamps[i] < oldestTimestamp) {oldestTimestamp = timestamps[i];oldestTimestampIndex = i;}}// 如果頁面不在物理頁面幀中,則發生頁面錯誤if (pageFault) {pageFaultCount++;pageFrames[oldestTimestampIndex] = pageNumber;timestamps[oldestTimestampIndex] = getCurrentTimestamp();}
}

(3)在Test類中,使用FIFO和LRU算法計算頁面錯誤次數。

PageGenerator ref = new PageGenerator(new Integer(args[0]).intValue());int[] referenceString = ref.getReferenceString();/** Use either the FIFO or LRU algorithms */
ReplacementAlgorithm fifo = new FIFO(new Integer(args[1]).intValue());
ReplacementAlgorithm lru = new LRU(new Integer(args[1]).intValue());// 插入頁面時輸出消息
for (int i = 0; i < referenceString.length; i++) {// System.out.println("inserting " + referenceString[i]);lru.insert(referenceString[i]);
}// 插入頁面時輸出消息
for (int i = 0; i < referenceString.length; i++) {// System.out.println("inserting " + referenceString[i]);fifo.insert(referenceString[i]);
}// 報告頁面錯誤總數
System.out.println("LRU faults = " + lru.getPageFaultCount());
System.out.println("FIFO faults = " + fifo.getPageFaultCount());

源碼


/*** This class generates page references ranging from 0 .. 9** Usage:*	PageGenerator gen = new PageGenerator()*	int[] ref = gen.getReferenceString();*/public class PageGenerator
{private static final int DEFAULT_SIZE = 100;private static final int RANGE = 9;int[] referenceString;public PageGenerator() {this(DEFAULT_SIZE);}public PageGenerator(int count) {if (count < 0)throw new IllegalArgumentException();java.util.Random generator = new java.util.Random();referenceString = new int[count];for (int i = 0; i < count; i++)referenceString[i] = generator.nextInt(RANGE + 1);}public int[] getReferenceString() {/*** comment out the following two lines to* generate random reference strings*/int[] str = {7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1};//int[] str = {1,2,3,4,1,2,5,1,2,3,4,5};return str;/*** and uncomment the following line*/	//return referenceString;}
}
/*** ReplacementAlgorithm.java **/public abstract class ReplacementAlgorithm
{// the number of page faultsprotected int pageFaultCount;// the number of physical page frameprotected int pageFrameCount;/*** @param pageFrameCount - the number of physical page frames*/public ReplacementAlgorithm(int pageFrameCount) {if (pageFrameCount < 0)throw new IllegalArgumentException();this.pageFrameCount = pageFrameCount;pageFaultCount = 0;}/*** @return - the number of page faults that occurred.*/public int getPageFaultCount() {return pageFaultCount;}/*** @param pageNumber - the page number to be inserted*/public abstract void insert(int pageNumber); 
}
public class FIFO extends ReplacementAlgorithm{private int[] pageFrames;private int currentIndex;public FIFO(int pageFrameCount){super(pageFrameCount);pageFrames = new int[pageFrameCount];currentIndex = 0;}@Overridepublic void insert(int pageNumber) {boolean pageFault = true;//check pages whether in pageFramesfor(int i =0;i<pageFrameCount;i++){if(pageFrames[i]==pageNumber){pageFault = false;break;}}//if pages not in pagesFrames,it happens faultsif(pageFault){pageFaultCount++;pageFrames[currentIndex] = pageNumber;currentIndex = (currentIndex+1)%pageFrameCount;}}
}
public class LRU extends ReplacementAlgorithm{private int[] pageFrames;private int[] timestamps;/*** @param pageFrameCount - the number of physical page frames*/public LRU(int pageFrameCount) {super(pageFrameCount);pageFrames = new int[pageFrameCount];timestamps = new int[pageFrameCount];}@Overridepublic void insert(int pageNumber) {boolean pageFault = true;int oldestTimestampIndex = 0;int oldestTimestamp = timestamps[0];//check pages whether in pagesFramesfor(int i =0;i<pageFrameCount;i++){if(pageFrames[i]==pageNumber){pageFault = false;//upgrade pageTimestapstimestamps[i] = getPageFaultCount();break;}if(timestamps[i]<oldestTimestamp){oldestTimestamp = timestamps[i];oldestTimestampIndex = i;}}//if not in pagesFrame,happen faultsif(pageFault){pageFaultCount++;pageFrames[oldestTimestampIndex]=pageNumber;timestamps[oldestTimestampIndex]=getCurrentTimestamp();}}//acquire current timestampprivate  int getCurrentTimestamp(){return pageFaultCount+1;}
}
/*** Test harness for LRU and FIFO page replacement algorithms**/public class Test
{public static void main(String[] args) {if (args.length != 2) {System.err.println("Usage: java Test <reference string size> <number of page frames>");System.exit(-1);}PageGenerator ref = new PageGenerator(Integer.valueOf(args[0]).intValue());int[] referenceString = ref.getReferenceString();/** Use either the FIFO or LRU algorithms */ReplacementAlgorithm fifo = new FIFO(Integer.valueOf(args[1]).intValue());ReplacementAlgorithm lru = new LRU(Integer.valueOf(args[1]).intValue());// output a message when inserting a pagefor (int i = 0; i < referenceString.length; i++) {//System.out.println("inserting " + referenceString[i]);lru.insert(referenceString[i]);}// output a message when inserting a pagefor (int i = 0; i < referenceString.length; i++) {//System.out.println("inserting " + referenceString[i]);fifo.insert(referenceString[i]);}// report the total number of page faultsSystem.out.println("LRU faults = " + lru.getPageFaultCount());System.out.println("FIFO faults = " + fifo.getPageFaultCount());}
}

運行結果

參數設置 20-3

參數設置 20-4?

?思考

在實現了 FIFO 與 LRU 算法后,給定引用序列,試驗不同頁幀的數量所產
生的缺頁次數。并分析:一個算法比另一好么?對給定引用序列,頁幀的最佳數
量是多少?假設給定引用序列 1,2,3,4,1,2,5,1,2,3,4,5,當頁幀
數分別為 3 和 4 時,用 FIFO 置換算法時缺頁中斷分別為多少?
根據代碼,可以通過修改 Test 類的 main 方法中的 args 數組來改變頁面幀的數量和引用序列的大小。以下是分別使用 FIFO 和 LRU 置換算法對給定引用序列進行測試的結果:
(1)當頁幀數為 3 時:
使用 FIFO 置換算法,缺頁次數為 9
使用 LRU 置換算法,缺頁次數為 9

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/81363.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/81363.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/81363.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

開發與AI融合的Windsurf編輯器

Windsurf編輯器是開發人員和人工智能真正融合在一起的地方&#xff0c;提供了一種感覺像文字魔術的編碼體驗。 手冊&#xff1a;Windsurf - Getting Started 下載鏈接&#xff1a;Download Windsurf Editor for Windows | Windsurf (formerly Codeium) 下載安裝 從上面的下載…

【Java】網絡編程(Socket)

網絡編程 Socket 我們開發的網絡應用程序位于應用層&#xff0c;TCP和UDP屬于傳輸層協議&#xff0c;在應用層如何使用傳輸層的服務呢&#xff1f;在應用層和傳輸層之間&#xff0c;則使用套接字Socket來進行分離 套接字就像是傳輸層為應用層開的一個小口&#xff0c;應用程…

【教程】Docker方式本地部署Overleaf

轉載請注明出處&#xff1a;小鋒學長生活大爆炸[xfxuezhagn.cn] 如果本文幫助到了你&#xff0c;歡迎[點贊、收藏、關注]哦~ 目錄 背景說明 下載倉庫 初始化配置 修改監聽IP和端口 自定義網站名稱 修改數據存放位置 更換Docker源 更換Docker存儲位置 啟動Overleaf 創…

根據用戶ID獲取所有子節點數據或是上級直屬節點數據

一、根據用戶ID獲取所有子節點&#xff0c;通過存儲過程來實現 CREATE DEFINERcrmeb% PROCEDURE proc_get_user_all_children( IN rootUid INTEGER, -- 要查詢的根用戶ID IN includeSelf BOOLEAN -- 是否包含自身(1包含,0不包含) ) BEGIN -- 聲明變…

計算機組成原理——數據的表示

2.1數據的表示 整理自Beokayy_ 1.進制轉換 十六進制與二進制的轉換 一位十六進制等于四位二進制 四位二進制等于一位十六進制 0x173A4C0001 0111 0011 1010 0100 1100 十六進制與十進制的轉換 十六轉十&#xff1a;每一位數字乘以相應的16的冪再相加 十轉十六&#xff1a…

基于MATLAB-GUI圖形界面的數字圖像處理

基于MATLAB GUI的數字圖像處理系統實現方案&#xff0c;包含常見圖像處理功能。代碼分為兩部分&#xff1a;GUI界面設計和回調函數實現。 %% 第一部分&#xff1a;創建GUI界面 (使用GUIDE) % 1. 打開GUIDE: guide % 2. 創建新GUI&#xff0c;添加以下控件&#xff1a; % - …

從裸機開發到實時操作系統:FreeRTOS詳解與實戰指南

從裸機開發到實時操作系統&#xff1a;FreeRTOS詳解與實戰指南 本文將帶你從零開始&#xff0c;深入理解嵌入式系統中的裸機開發與實時操作系統&#xff0c;以FreeRTOS為例&#xff0c;全面剖析其核心概念、工作原理及應用場景。無論你是嵌入式新手還是希望提升技能的開發者&am…

zabbix7.2最新版本 nginx自定義監控(三) 設置觸發器

安裝zabbix-get服務 在zabbix-server端口安裝zabbix-get服務 [rootlocalhost ~]# dnf install -y zabbix-get Last metadata expiration check: 1:55:49 ago on Wed 14 May 2025 09:24:49 AM CST. Dependencies resolved. Package Architectur…

在 Kotlin 中,什么是解構,如何使用?

在 Kotlin 中&#xff0c;解構是一種語法糖&#xff0c;允許將一個對象分解為多個獨立的變量。 這種特性可以讓代碼更簡潔、易讀&#xff0c;尤其適用于處理數據類、集合&#xff08;如 Pair、Map&#xff09;或其他結構化數據。 1 解構的核心概念 解構通過定義 componentN()…

html的鼠標點擊事件有哪些寫法

在HTML中&#xff0c;鼠標點擊事件的實現方式多樣&#xff0c;以下從基礎語法到現代實踐為您詳細梳理&#xff1a; 一、基礎寫法&#xff1a;直接內聯事件屬性 在HTML標簽內通過on前綴事件屬性綁定處理函數&#xff0c;適合簡單交互場景&#xff1a; <!-- 單擊事件 -->…

基于EFISH-SCB-RK3576/SAIL-RK3576的智能垃圾分類站技術方案

&#xff08;國產化替代J1900的環保物聯網解決方案&#xff09; 一、硬件架構設計? ?多模態感知系統? ?高精度識別模塊?&#xff1a; 雙光譜成像&#xff08;RGB近紅外&#xff09;融合NPU加速ResNet50模型&#xff0c;支持40垃圾品類識別&#xff08;準確率>99.5%&am…

PYTHON訓練營DAY27

裝飾器 編寫一個裝飾器 logger&#xff0c;在函數執行前后打印日志信息&#xff08;如函數名、參數、返回值&#xff09; logger def multiply(a, b):return a * bmultiply(2, 3) # 輸出: # 開始執行函數 multiply&#xff0c;參數: (2, 3), {} # 函數 multiply 執行完畢&a…

Android Studio 中 build、assemble、assembleDebug 和 assembleRelease 構建 aar 的區別

上一篇&#xff1a;Tasks中沒有build選項的解決辦法 概述&#xff1a; 在構建 aar 包時通常會在下面的選項中進行構建&#xff0c;但是對于如何構建&#xff0c;選擇哪種方式構建我還是處于懵逼狀態&#xff0c;所以我整理了一下幾種構建方式的區別以及如何選擇。 1. build…

視頻質量分析時,遇到不同分辨率的對照視頻和源視頻,分辨率對齊的正確順序。

背景 我們平時在做視頻轉碼后&#xff0c;會用VMAF/PSNR得評分工具進行視頻對比的評分&#xff0c;但是這幾種客觀評分方式都有一個要求就是分辨率要一模一樣&#xff0c;因為這樣才對像素點做數學運算。 但是分辨率對齊其實有兩種選擇&#xff0c;例如源視頻是1080P&#xf…

【技巧】離線安裝docker鏡像的方法

回到目錄 【技巧】離線安裝docker鏡像的方法 0. 為什么需要離線安裝&#xff1f; 第一、 由于docker hub被墻&#xff0c;所以 拉取鏡像需要配置國內鏡像源 第二、有一些特殊行業服務器無法接入互聯網&#xff0c;需要手工安裝鏡像 1. 可以正常拉取鏡像服務器操作 服務器…

計算機網絡 : 網絡基礎

計算機網絡 &#xff1a; 網絡基礎 目錄 計算機網絡 &#xff1a; 網絡基礎引言1. 網絡發展背景2. 初始協議2.1 初始協議2.2 協議分層2.2.1 軟件分層的好處2.2.2 OSI七層模型2.2.3 TCP/IP五層&#xff08;四層&#xff09;模型 2.3 TCP/IP協議2.3.1TCP/IP協議與操作系統的關系&…

【2025最新】Windows系統裝VSCode搭建C/C++開發環境(附帶所有安裝包)

文章目錄 為什么選擇VSCode作為C/C開發工具&#xff1f;一、VSCode安裝過程&#xff08;超簡單&#xff01;&#xff09;二、VSCode中文界面設置&#xff08;再也不用對著英文發愁&#xff01;&#xff09;三、安裝C/C插件&#xff08;編程必備神器&#xff01;&#xff09;四、…

Jmeter 安裝包與界面漢化

Jmeter 安裝包&#xff1a; 通過網盤分享的文件&#xff1a;CSDN-apache-jmeter-5.5 鏈接: https://pan.baidu.com/s/17gK98NxS19oKmkdRhGepBA?pwd1234 提取碼: 1234 Jmeter界面漢化&#xff1a;

HandlerInterceptor介紹-筆記

1. HandlerInterceptor簡介 org.springframework.web.servlet.HandlerInterceptor 是 Spring MVC 中用于攔截 HTTP 請求的核心接口。 public interface HandlerInterceptor {default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object ha…

C++循環效率比較與優化建議

在 C++ 中,不同循環結構(如 for、while、do-while、基于范圍的 for)在優化后的性能通常是等效的,因為現代編譯器會對它們進行底層優化,生成相似的機器代碼。循環的效率更多取決于循環體內的操作和數據訪問模式,而非循環結構本身的選擇。以下是關鍵點總結: 1. 傳統循環的…