操作系統第5次實驗報告:內存管理


  • 姓名:倪曉東
  • 學號:201821121020
  • 班級: 計算1811

1. 記錄內存空間使用情況

解釋你是如何記錄內存空間使用情況,給出關鍵代碼。

/*記錄內存空間使用情況,每個進程分配到的內存塊描述*/
struct allocated_block
{
    int pid;
    int size;                //進程大小
    int start_addr;          //進程分配到的內存塊的起始地址
    char process_name[PROCESS_NAME_LEN];  //進程名
    struct allocated_block *next;   //指向下一個進程控制塊
};

 

2. 記錄空閑分區

用什么樣的方法記錄內存空閑區,給出關鍵代碼。

//空閑分區,描述每一個空閑塊的數據結構
struct free_block_type
{
    int size;        //空閑塊大小
    int start_addr;  //空閑塊起始位置
    struct free_block_type *next;  //指向下一個空閑塊
};
//指向內存中空閑塊鏈表的首地址
struct free_block_type *free_block= NULL;

  空閑分區鏈表:

//按首次適配算法重新整理內存空閑塊鏈表,按空閑塊首地址排序
int rearrange_FF()
{
    struct free_block_type *head= free_block;
    struct free_block_type *forehand,*pre,*rear;
    int i;
    if(head== NULL)
        return -1;
    for(i= 0;i< free_block_count-1;i++)
    {
        forehand= head;
        pre= forehand->next;
        rear= pre->next;
        while(pre->next!= NULL)
        {
            if(forehand== head&&forehand->start_addr>= pre->start_addr)
            {
                //比較空閑鏈表中第一個空閑塊與第二個空閑塊的開始地址的大小
                head->next= pre->next;
                pre->next= head;
                head= pre;
                forehand= head->next;
                pre= forehand->next;
                rear= pre->next;
            }
            else if(pre->start_addr>= rear->start_addr)
            {
                //比較鏈表中其它相鄰兩個結點的開始地址的大小
                pre->next= rear->next;
                forehand->next= rear;
                rear->next= pre;
                forehand= rear;
                rear= pre->next;
            }
            else
            {
                forehand= pre;
                pre= rear;
                rear= rear->next;
            }
        }
    }
    return 0;
}

  

3. 內存分配算法

使用首次適配算法內存分配:

//按照首次適應算法給新進程分配內存空間
int allocate_FF(struct allocated_block *ab)
{
    int ret;
    struct free_block_type *pre= NULL,*ff= free_block;
    if(ff== NULL)
        return -1;
    while(ff!= NULL)
    {
        if(ff->size>= ab->size)
        {
            ret= allocate(pre,ff,ab);
            break;
        }
        pre= ff;
        pre= pre->next;
    }
    if(ff== NULL&&current_free_mem_size> ab->size)
        ret= mem_retrench(ab);
    else
        ret= -2;
    rearrange_FF();
    return ret;
}

4. 內存釋放算法

int exit()
{
    struct allocated_block *allocated_ab,*allocated_pre;
    struct free_block_type *free_ab,*free_pre;
    free_pre= free_block;
    allocated_pre= allocated_block_head;
    if(free_pre!= NULL)   //鏈表不為空 
    {
        free_ab= free_pre->next;
        while(free_ab!= NULL)
        {
            free(free_pre);   //釋放當前節點 
            free_pre= free_ab; 
            free_ab= free_ab->next; //節點后移 
        }
    }
    if(allocated_pre!= NULL)
    {
        allocated_ab= allocated_pre->next;
        while(allocated_ab!= NULL)
        {
            free(allocated_pre);  //釋放節點 
            allocated_pre= allocated_ab;
            allocated_ab= allocated_ab->next;  //節點后移 
        }
    }
    allocated_ab= allocated_ab->next;
    return 0;
}

刪除進程,歸還分配的存儲空間,並刪除描述該進程內存分配的結點

void kill_process()
{
    struct allocated_block *ab;
    int pid;
    printf("Kill Process,pid=");//刪除進程號為
    scanf("%d",&pid);
    getchar();
    ab= find_process(pid);  //找到pid對應的鏈表節點
    if(ab!= NULL)
    {
        free_mem(ab);  //釋放ab所表示的分配區
        dispose(ab);   //釋放ab數據結構結點
    }
}

在進程分配鏈表中尋找指定進程

struct allocated_block* find_process(int pid)
{
    struct allocated_block *ab= allocated_block_head;
    if(ab== NULL)
    {
        printf("不存在!\n");
        return NULL;
    }
    while(ab->pid!= pid&&ab->next!= NULL)//查找整個鏈表 
        ab= ab->next;
    if(ab->next== NULL&&ab->pid!= pid)//找不到 
    {
        printf("error!\n");
        return NULL;
    }
    return ab;
}

  

5. 運行結果

(1)產生測試數據

設置內存大小為1000,每次為進程分配1-100內存大小:

 設置內存大小為200,每次為進程分配1-20內存大小:

(2)解釋結果

內存總大小為200,每次為進程分配1-20內存

 如圖所示,創建的第一個進程號PID=1,進程名稱為PEOCESSNAME-01,內存起始地址為0,內存大小為2,空閑區首地址為2,剩余內存198。

 

 如圖所示,創建的第二個進程號PID=2,進程名稱為PEOCESS-02,內存起始地址為2,分配到的內存大小為8,空閑區首地址為10,剩余內存190。

  如圖所示,創建的第二個進程號PID=3,進程名稱為PEOCESS-03,內存起始地址為10,分配到的內存大小為15,空閑區首地址為25,剩余內存175。

 

  如圖所示,創建的第二個進程號PID=4,進程名稱為PEOCESS-04,內存起始地址為25,分配到的內存大小為1,空閑區首地址為26,剩余內存174。

 

 小結:

       首次適配算法從空閑區的第一個表目起查找該表,把最先能夠滿足要求的空閑區分配給進程,這種方法目的在於減少查找時間。為適應這種算法,空閑區鏈中的空閑分區要按地址由低到高進行排序。該算法優先使用低址部分空閑區,在低址空間造成許多小的空閑區,在高地址空間保留大的空閑區。但是在實際使用過程中,由於優先使用低址的可用空閑區,低址部分被不斷進行分配,但又不能保證剛好完全利用,所以會留下很多不能被使用小空閑區,而且每次為進程分配內存從低址開始尋找,就要和這些小空閑區適配,會影響速率。

 參考文獻:https://github.com/City-Zero/LinuxTest/blob/master/OSex/mem_manager/mm.c

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM