操作系統第五次實驗報告——記憶體管理

来源:https://www.cnblogs.com/MilkoSilver/archive/2020/05/17/12904806.html
-Advertisement-
Play Games

0 個人信息 張櫻姿 201821121038 計算1812 1 實驗目的 通過編程進一步瞭解記憶體管理。 2 實驗內容 在伺服器上用Vim編寫一個程式:模擬實現某個記憶體管理演算法,測試給出結果,並對解釋運行結果。 3 實驗報告 3.1 記錄記憶體空間使用情況 使用鏈表記錄記憶體空間使用情況。 1 //每個 ...


0 個人信息

  • 張櫻姿
  • 201821121038
  • 計算1812

1 實驗目的

  • 通過編程進一步瞭解記憶體管理。

2 實驗內容

  • 在伺服器上用Vim編寫一個程式:模擬實現某個記憶體管理演算法,測試給出結果,並對解釋運行結果。

3 實驗報告

  3.1 記錄記憶體空間使用情況

   使用鏈表記錄記憶體空間使用情況。

 1 //每個進程分配到的記憶體塊
 2 typedef struct allocated_block{
 3     int pid;           //進程號
 4     int size;          //進程分配到的記憶體塊大小
 5     int start_addr; //記憶體塊起始地址
 6     char process_name[NAME_LEN]; //進程名
 7     struct allocated_block *next;       //指向下一個記憶體塊的指針
 8 }AB;    
 9 
10 //進程分配記憶體塊鏈表的首指針
11 AB *allocated_block_head = NULL; 

  3.2 記錄空閑分區

   同樣也使用鏈表來記錄空閑分區。

1 //每個空閑塊
2 typedef struct free_block_type{
3     int size;            //空閑塊大小
4     int start_addr;   //空閑塊起始地址
5     struct free_block_type *next;   //指向下一個空閑塊
6 }FBT;
7 
8 //指向記憶體中空閑塊鏈表的首指針
9 FBT *free_block;        

  3.3 記憶體分配演算法

   最佳分配演算法(Best Fit Allocation)的原理是空閑分區列表按照大小排序,在分配時,查找一個合適的分區(分配n位元組分區時,查找並使用不小於n的最小空間分區);在釋放時,查找並且合併臨近的空閑分區(如果找到的話)。

 1 //執行分配記憶體
 2 void do_allocate_mem(AB *ab){
 3     int request = ab->size;
 4     FBT *tmp = free_block;
 5     while(tmp != NULL){
 6         if(tmp->size >= request){
 7             //分配
 8             ab->start_addr = tmp->start_addr;
 9             int shengyu = tmp->size - request;
10             tmp->size = shengyu;
11             tmp->start_addr = tmp->start_addr + request;
12         
13             return ;
14         }
15         tmp = tmp->next;
16     }
17 }
18 
19 //分配記憶體模塊
20 int allocate_mem(AB *ab){
21     FBT *fbt,*pre;
22     int request_size=ab->size;
23     fbt = pre = free_block;
24     //嘗試尋找可分配空閑
25     int f = find_free_mem(request_size);
26     if(f == -1){
27         //不夠分配
28         printf("空閑記憶體不足,記憶體分配失敗!\n");
29         return -1;
30     }else{
31         if(f == 0){
32             //需要記憶體緊縮才能分配
33             memory_compact();
34         }
35         //執行分配
36         do_allocate_mem(ab);
37     }
38     //重新排布空閑分區
39     rearrange(ma_algorithm);
40     return 1;
41 } 
42 
43 //最佳適應演算法,空閑分區按大小從小到大排序
44 void rearrange_BF(){
45     if(free_block == NULL || free_block->next == NULL)
46         return;
47     FBT *t1,*t2,*head;
48     head = free_block;
49     //遍歷整個空閑塊列表,比較找到最小的一塊空閑塊
50     for(t1 = head->next;t1;t1 = t1->next){
51         for(t2 = head;t2 != t1;t2=t2->next){
52             if(t2->size > t2->next->size){
53                 int tmp = t2->start_addr;
54                 t2->start_addr = t2->next->start_addr;
55                 t2->next->start_addr = tmp;
56 
57                 tmp = t2->size;
58                 t2->size = t2->next->size;
59                 t2->next->size = tmp;
60             }
61         }
62     }
63 }

  3.4 記憶體釋放演算法

 1 //釋放鏈表節點
 2 int dispose(AB *free_ab){
 3     AB *pre,*ab;
 4     if(free_ab == allocated_block_head){
 5         //如果要釋放第一個節點
 6         allocated_block_head = allocated_block_head->next;
 7         free(free_ab);
 8         return 1;
 9     }
10     pre = allocated_block_head;
11     ab = allocated_block_head->next;
12     while(ab!=free_ab){
13         pre = ab;
14         ab = ab->next;
15     }
16     pre->next = ab->next;
17     free(ab);
18     return 2;
19 }
20 
21 //更新分區表
22 int free_mem(AB *ab){
23     //將ab所表示的已分配區歸還,併進行可能的合併
24     int algorithm = ma_algorithm;
25     FBT *fbt,*pre,*work;
26     fbt = (FBT*)malloc(sizeof(FBT));
27     if(!fbt) return -1;
28     fbt->size = ab->size;
29     fbt->start_addr = ab->start_addr;
30 
31     //插至末尾
32     work = free_block;
33     if(work == NULL){
34         free_block = fbt;
35         fbt->next == NULL;
36     }else{
37         while(work ->next != NULL){
38             work = work->next;
39         }
40         fbt->next = work->next;
41         work->next = fbt;
42     }
43     //按地址重新排布
44     rearrange_BF();
45 
46     //合併可能分區;即若兩空閑分區相連則合併
47     pre = free_block;
48     while(pre->next){
49         work = pre->next;
50         if(pre->start_addr + pre->size == work->start_addr ){
51             pre->size = pre->size + work->size;
52             pre->next = work->next;
53             free(work);
54             continue;
55         }else{
56             pre = pre->next;
57         }
58     }
59     //按照當前演算法排序
60     rearrange(ma_algorithm);
61     return 1;
62 }
63 
64 //釋放已分配的記憶體空間,刪除描述該進程分配到的記憶體塊的節點
65 int kill_process(int pid){
66     AB *ab;
67     ab = find_process(pid);
68     if(ab!=NULL){
69         //釋放ab所表示的分配表
70         free_mem(ab);    
71         //釋放ab數據結構節點
72         dispose(ab);    
73         return 0;
74     }else{
75         return -1;
76     }
77 }

  3.5 運行結果

    3.5.1 產生測試數據

      隨機為3個進程分配、釋放記憶體10次以上,即隨機產生10組以上數據。

 1 int main(int argc, char const *argv[]){
 2     /*
 3         sel1=0表示為某進程分配記憶體空間 
 4         sel1=1表示為釋放某進程占用的記憶體空間 
 5     */ 
 6     int sel1,sel2; 
 7     int total=0; //記錄分配記憶體的次數 
 8     free_block = init_free_block(mem_size); //初始化空閑區
 9     
10     Prc prc[PROCESS_NUM];//存放要載入的進程
11     init_program(prc,PROCESS_NUM);//對這幾個程進程進行初始化 
12     srand( (unsigned)time( NULL ) );  
13     
14     for(int i=0;i<DATA_NUM;++i)
15     {
16         sel1=rand()%2;
17         int count=0;
18         //統計三個進程中有多少個進程已經分配記憶體 
19         for(int j=0;j<PROCESS_NUM;++j){
20             if(prc[j].pid!=-1)
21                 count++;
22         }
23         //如果全部分配進程或者進程分配到達5次,那麼就不能繼續分配記憶體改為釋放記憶體 
24         if((count==PROCESS_NUM && sel1==0)||total==5)
25             sel1=1;
26         //如果全部未分配進程,那麼就不能繼續釋放記憶體 
27         if(count==0 && sel1==1)
28             sel1=0;
29         if(sel1==0)//為進程分配記憶體 
30         {
31             //隨機找到一個未分配記憶體的進程 
32             do{
33                 sel2=rand()%PROCESS_NUM;
34             }while(prc[sel2].pid!=-1);
35             alloc_process(prc[sel2]);//分配記憶體空間 
36             prc[sel2].pid=pid;//改變標記 
37             total++;
38             display_mem_usage();//顯示 
39         }
40         else//釋放進程占用的記憶體空間 
41         {
42             //隨機找到一個可釋放進程 
43             do{
44                 sel2=rand()%PROCESS_NUM;
45             }while(prc[sel2].pid==-1);
46             kill_process(prc[sel2].pid);//釋放記憶體空間 
47             prc[sel2].pid=-1;//改變標記 
48             display_mem_usage();//顯示 
49         }
50     }
51 }

    3.5.2 解釋結果

     初始的空閑塊大小1024KB,

     ①第一次分配結果:

     為PID為1的進程分配大小為24KB的記憶體空間,起始地址為0,分配完成後的空閑空間為1000KB,起始地址為24。

    ②第二次分配結果:

     為PID為2的進程分配大小為74KB的記憶體空間,起始地址為24,分配完成後的空閑空間為926KB,起始地址為98。

    ③第三次分配結果:

    為PID為3的進程分配大小為36KB的記憶體空間,起始地址為98,分配完成後的空閑空間為890KB,起始地址為134。     

    ④第四次分配結果:

    將PID為3的進程釋放,空閑空間變為926KB,起始地址為98。

    ⑤第五次分配結果:

     將PID為1的進程釋放,空閑空間變為兩塊,一塊大小926KB,起始地址為98。另一塊大小24KB,起始地址為0。

4 References

 

  

 

    


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • gzip命令 功能說明:gzip命令會對系統文件進行壓縮和解壓縮,壓縮完成後,系統會自動在原文件後加上.gz的擴展名,並刪除原文件。只能對文件進行壓縮,不能對目錄進行壓縮。 用法:gzip [OPTION]... FILE... | 選項 | 作用 | | : : | : | | d | 解壓縮,相 ...
  • 二、文件編輯和查找類 (一)vi/vim快捷鍵及面試題系列 選擇 1.vi保存退出命令(B) ​ A.w! ​ B.wq! ​ C.q! ​ D.www 2.vi移動游標到文件最後一行(A) ​ A.G ​ B.g ​ C.ggg ​ D.4444 3.vi刪除一行的命令(A) ​ A.dd ​ B ...
  • 我們在日常工作中,不管是系統管理員、程式員、還是技術工程師,如果想登陸到 Linux 伺服器,不可能總是跑到機房去工作,通常我們需要一個工具幫我們去做遠程連接,這樣我們只需要用筆記本電腦就可以連接到伺服器上了。一般用的比較多的工具是 XShell 和 PuTTY。PuTTY我之前有做過詳細的介紹,感 ...
  • 背景 By 魯迅 By 高爾基 說明: 1. Kernel版本:4.14 2. ARM64處理器,Contex A53,雙核 3. 使用工具:Source Insight 3.5, Visio 1. 概述 信號量 ,是操作系統中一種常用的同步與互斥的機制; 信號量允許多個進程(計數值 1)同時進入臨 ...
  • 如何在Vmware安裝Linux CentOS 7.7系統,並且是最小化安裝。之後進行必要的配置修改,並實現基礎優化。最後做一個快照。 ...
  • cat選項分析 選項解析: -A, --show-all 等價於 -vET -b, --number-nonblank 對非空輸出行(包括僅僅有空格的行)編號,空輸出行,指的是該行沒有任何內容,即連續2次敲擊回車按鈕。 -e 等價於 -vE -E, --show-ends 在每行結束處顯示 $ -n ...
  • 一個Linux系統,根據版本不同,大約包含240~260個系統調用。為了使得操作更為簡單,更加便於應用程式使用,Linux系統對系統調用的部分功能進行了再次封裝,形成了公用函數庫,以供應用程式調用。公用函數庫中的一個方法,實質上是若幹個系統調用以特定的邏輯組合而成。 ...
  • 如果現在需要在 Linux 伺服器上執行一系列命令(比如搭建 LNMP 環境)我應該會第一時間想到想辦法寫個 Shell 腳本,然後扔上去執行以下看看結果。 然而一貫懶惰的我並不想這麼去執行 Shell 和一些重覆命令。所以俺尋思可以有個方法本地直接在伺服器端執行腳本,尋思生異端,這時候有某大技霸告 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...