📜  内存管理中所有分区分配方法的实现

📅  最后修改于: 2021-05-31 22:24:45             🧑  作者: Mango

先决条件:内存管理中的分区分配方法
在“分区分配”中,当有多个可用分区来自由容纳一个进程请求时,必须选择一个分区。为了选择特定的分区,需要一种分区分配方法。如果避免内部碎片,则分区分配方法被认为更好。

考虑以下数据进行处理:

Process No. Process Size
1 88
2 192
3 277
4 365
5 489
Consider the following data for memory slots:
Memory Block No. Memory Block Size
1 400
2 500
3 300
4 200
5 100

以下是各种分区分配方案及其相对于上述给定数据的实现。

1.首先适合

此方法保留按内存位置(从低位到高位内存)组织的作业的忙/闲列表。在这种方法中,第一作业要求具有大于或等于其大小的空间的第一可用内存。操作系统不会搜索适当的分区,而只是将作业分配给具有足够大小的最近的可用内存分区。

以下是首次拟合算法的实现:

// C++ program for the implementation
// of the First Fit algorithm
#include 
#include 
#include 
using namespace std;
  
// Process Class
class process {
public:
    // Size & number of process
    size_t size;
    pid_t no;
};
  
// Memory Class
class memory {
public:
    size_t size;
  
    // Number of memory & queue of space
    // occupied by process
    pid_t no;
    queue space_occupied;
  
    // Function to push process in a block
    void push(const process p)
    {
        if (p.size <= size) {
            space_occupied.push(p);
            size -= p.size;
        }
    }
  
    // Function to pop and return the
    // process from the block
    process pop()
    {
        process p;
  
        // If space occupied is empty
        if (!space_occupied.empty()) {
            p = space_occupied.front();
            space_occupied.pop();
            size += p.size;
            return p;
        }
    }
  
    // Function to check if block is
    // completely empty
    bool empty()
    {
        return space_occupied.empty();
    }
};
  
// Function to get data of processess
// allocated using first fit
vector first_fit(vector memory_blocks,
                         queue processess)
{
    int i = 0;
    bool done, done1;
    memory na;
    na.no = -10;
    while (!processess.empty()) {
        done = 0;
        for (i = 0; i < memory_blocks.size(); i++) {
            done1 = 0;
            if (memory_blocks.at(i).size
                >= processess.front().size) {
                memory_blocks.at(i).push(processess.front());
                done = 1;
                done1 = 1;
                break;
            }
        }
  
        // If process is done
        if (done == 0 && done1 == 0) {
            na.size += processess.front().size;
            na.push(processess.front());
        }
  
        // pop the process
        processess.pop();
    }
    if (!na.space_occupied.empty())
        memory_blocks.push_back(na);
    return memory_blocks;
}
  
// Function to display the allocation
// of all processess
void display(vector memory_blocks)
{
    int i = 0, temp = 0;
    process p;
    cout << "+-------------+--------------+--------------+"
         << endl;
    cout << "| Process no. | Process size | Memory block |"
         << endl;
    cout << "+-------------+--------------+--------------+"
         << endl;
  
    // Traverse memory blocks size
    for (i = 0; i < memory_blocks.size(); i++) {
  
        // While memory block size is not empty
        while (!memory_blocks.at(i).empty()) {
            p = memory_blocks.at(i).pop();
            temp = to_string(p.no).length();
            cout << "|" << string(7 - temp / 2 - temp % 2, ' ')
                 << p.no << string(6 - temp / 2, ' ')
                 << "|";
  
            temp = to_string(p.size).length();
            cout << string(7 - temp / 2 - temp % 2, ' ')
                 << p.size
                 << string(7 - temp / 2, ' ') << "|";
  
            temp = to_string(memory_blocks.at(i).no).length();
            cout << string(7 - temp / 2 - temp % 2, ' ');
  
            // If memory blocks is assigned
            if (memory_blocks.at(i).no != -10) {
                cout << memory_blocks.at(i).no;
            }
  
            // Else memory blocks is assigned
            else {
                cout << "N/A";
            }
            cout << string(7 - temp / 2, ' ')
                 << "|" << endl;
        }
    }
    cout << "+-------------+--------------+--------------+"
         << endl;
}
  
// Driver Code
int main()
{
    // Declare memory blocks
    vector memory_blocks(5);
  
    // Declare first fit blocks
    vector first_fit_blocks;
  
    // Declare queue of all processess
    queue processess;
    process temp;
  
    // Set sample data
    memory_blocks[0].no = 1;
    memory_blocks[0].size = 400;
  
    memory_blocks[1].no = 2;
    memory_blocks[1].size = 500;
  
    memory_blocks[2].no = 3;
    memory_blocks[2].size = 300;
  
    memory_blocks[3].no = 4;
    memory_blocks[3].size = 200;
  
    memory_blocks[4].no = 5;
    memory_blocks[4].size = 100;
  
    temp.no = 1;
    temp.size = 88;
  
    // Push the process
    processess.push(temp);
  
    temp.no = 2;
    temp.size = 192;
  
    // Push the process
    processess.push(temp);
  
    temp.no = 3;
    temp.size = 277;
  
    // Push the process
    processess.push(temp);
  
    temp.no = 4;
    temp.size = 365;
  
    // Push the process
    processess.push(temp);
  
    temp.no = 5;
    temp.size = 489;
  
    // Push the process
    processess.push(temp);
  
    // Get the data
    first_fit_blocks = first_fit(memory_blocks, processess);
  
    // Display the data
    display(first_fit_blocks);
    memory_blocks.clear();
    memory_blocks.shrink_to_fit();
    first_fit_blocks.clear();
    first_fit_blocks.shrink_to_fit();
    return 0;
}
输出:
+-------------+--------------+--------------+
| Process no. | Process size | Memory block |
+-------------+--------------+--------------+
|      1      |      88      |      1       |
|      2      |     192      |      1       |
|      3      |     277      |      2       |
|      4      |     365      |     N/A      |
|      5      |     489      |     N/A      |
+-------------+--------------+--------------+

2.下一个适合

下一个契合度是“首次契合度”的修改版本。它首先是找到一个可用分区的开始,但是在下次调用时,它将从中断的地方开始搜索,而不是从头开始。该策略使用了漫游指针。指针沿着存储链移动以搜索下一个拟合。这有助于避免总是从空闲块链的开头(开头)开始使用内存。

以下是Next Fit算法的实现:

// C++ program for the implementation
// of the Next Fit algorithm
#include 
#include 
#include 
using namespace std;
  
// Process Class
class process {
public:
    // Size & number of process
    size_t size;
    pid_t no;
};
  
// Memory Class
class memory {
public:
    size_t size;
  
    // Number of memory & queue of space
    // occupied by process
    pid_t no;
    queue space_occupied;
  
    // Function to push process in a block
    void push(const process p)
    {
        if (p.size <= size) {
            space_occupied.push(p);
            size -= p.size;
        }
    }
  
    // Function to pop and return the
    // process from the block
    process pop()
    {
        process p;
  
        // If space occupied is empty
        if (!space_occupied.empty()) {
            p = space_occupied.front();
            space_occupied.pop();
            size += p.size;
            return p;
        }
    }
  
    // Function to check if block is
    // completely empty
    bool empty()
    {
        return space_occupied.empty();
    }
};
  
// Function to get data of processess
// allocated using Next Fit
vector next_fit(vector memory_blocks,
                        queue processess)
{
    int i = 0;
    bool done, done1;
    memory na;
    na.no = -10;
  
    // Loop till process is empty
    while (!processess.empty()) {
        done1 = 0;
  
        // Traverse memory_blocks
        for (i = 0; i < memory_blocks.size(); i++) {
            done = 0;
  
            // If process is not empty
            if (!processess.empty() && memory_blocks.at(i).size >= processess.front().size) {
                memory_blocks.at(i).push(processess.front());
                done = 1;
                done1 = 1;
                processess.pop();
            }
        }
        if (!processess.empty() && done == 0 && done1 == 0) {
            na.size += processess.front().size;
            na.push(processess.front());
            processess.pop();
        }
    }
  
    // If space is not occupied push
    // the memory_blocks na
    if (!na.space_occupied.empty()) {
        memory_blocks.push_back(na);
    }
  
    return memory_blocks;
}
  
// Function to display the allocation
// of all processess
void display(vector memory_blocks)
{
    int i = 0, temp = 0;
    process p;
    cout << "+-------------+--------------+--------------+"
         << endl;
    cout << "| Process no. | Process size | Memory block |"
         << endl;
    cout << "+-------------+--------------+--------------+"
         << endl;
  
    // Traverse memory blocks size
    for (i = 0; i < memory_blocks.size(); i++) {
  
        // While memory block size is not empty
        while (!memory_blocks.at(i).empty()) {
            p = memory_blocks.at(i).pop();
            temp = to_string(p.no).length();
            cout << "|" << string(7 - temp / 2 - temp % 2, ' ')
                 << p.no << string(6 - temp / 2, ' ')
                 << "|";
  
            temp = to_string(p.size).length();
            cout << string(7 - temp / 2 - temp % 2, ' ')
                 << p.size
                 << string(7 - temp / 2, ' ') << "|";
  
            temp = to_string(memory_blocks.at(i).no).length();
            cout << string(7 - temp / 2 - temp % 2, ' ');
  
            // If memory blocks is assigned
            if (memory_blocks.at(i).no != -10) {
                cout << memory_blocks.at(i).no;
            }
  
            // Else memory blocks is assigned
            else {
                cout << "N/A";
            }
            cout << string(7 - temp / 2, ' ')
                 << "|" << endl;
        }
    }
    cout << "+-------------+--------------+--------------+"
         << endl;
}
  
// Driver Code
int main()
{
    // Declare memory blocks
    vector memory_blocks(5);
  
    // Declare next fit blocks
    vector next_fit_blocks;
  
    // Declare queue of all processess
    queue processess;
    process temp;
  
    // Set sample data
    memory_blocks[0].no = 1;
    memory_blocks[0].size = 400;
  
    memory_blocks[1].no = 2;
    memory_blocks[1].size = 500;
  
    memory_blocks[2].no = 3;
    memory_blocks[2].size = 300;
  
    memory_blocks[3].no = 4;
    memory_blocks[3].size = 200;
  
    memory_blocks[4].no = 5;
    memory_blocks[4].size = 100;
  
    temp.no = 1;
    temp.size = 88;
  
    // Push the process
    processess.push(temp);
    temp.no = 2;
    temp.size = 192;
  
    // Push the process
    processess.push(temp);
    temp.no = 3;
    temp.size = 277;
  
    // Push the process
    processess.push(temp);
    temp.no = 4;
    temp.size = 365;
  
    // Push the process
    processess.push(temp);
    temp.no = 5;
    temp.size = 489;
  
    // Push the process
    processess.push(temp);
  
    // Get the data
    next_fit_blocks = next_fit(memory_blocks,
                               processess);
  
    // Display the data
    display(next_fit_blocks);
    memory_blocks.clear();
    memory_blocks.shrink_to_fit();
    next_fit_blocks.clear();
    next_fit_blocks.shrink_to_fit();
    return 0;
}
输出:
+-------------+--------------+--------------+
| Process no. | Process size | Memory block |
+-------------+--------------+--------------+
|      1      |      88      |      1       |
|      2      |     192      |      2       |
|      3      |     277      |      3       |
|      4      |     365      |     N/A      |
|      5      |     489      |     N/A      |
+-------------+--------------+--------------+

3.最差的身材

最差拟合为分区分配一个进程,该进程在主内存中可用的可用分区中最大。如果较大的进程在以后出现,则内存将没有空间容纳它。

以下是最差拟合算法的实现:

// C++ program for the implementation
// of the Worst Fit algorithm
#include 
#include 
#include 
using namespace std;
  
// Process Class
class process {
public:
    // Size & number of process
    size_t size;
    pid_t no;
};
  
// Memory Class
class memory {
public:
    size_t size;
  
    // Number of memory & queue of space
    // occupied by process
    pid_t no;
    queue space_occupied;
  
    // Function to push process in a block
    void push(const process p)
    {
        if (p.size <= size) {
            space_occupied.push(p);
            size -= p.size;
        }
    }
  
    // Function to pop and return the
    // process from the block
    process pop()
    {
        process p;
  
        // If space occupied is empty
        if (!space_occupied.empty()) {
            p = space_occupied.front();
            space_occupied.pop();
            size += p.size;
            return p;
        }
    }
  
    // Function to check if block is
    // completely empty
    bool empty()
    {
        return space_occupied.empty();
    }
};
  
// Function to get data of processess
// allocated using Worst Fit
vector worst_fit(vector memory_blocks,
                         queue processess)
{
    int i = 0, index = 0, max;
    memory na;
    na.no = -10;
  
    // Loop till process queue is not empty
    while (!processess.empty()) {
        max = 0;
  
        // Traverse the memory_blocks
        for (i = 0; i < memory_blocks.size(); i++) {
            if (memory_blocks.at(i).size >= processess.front().size
                && memory_blocks.at(i).size > max) {
                max = memory_blocks.at(i).size;
                index = i;
            }
        }
        if (max != 0) {
            memory_blocks.at(index).push(processess.front());
        }
  
        else {
            na.size += processess.front().size;
            na.push(processess.front());
        }
  
        // Pop the current process
        processess.pop();
    }
  
    // If space is not occupied
    if (!na.space_occupied.empty()) {
        memory_blocks.push_back(na);
    }
  
    // Return the memory
    return memory_blocks;
}
  
// Function to display the allocation
// of all processess
void display(vector memory_blocks)
{
    int i = 0, temp = 0;
    process p;
    cout << "+-------------+--------------+--------------+"
         << endl;
    cout << "| Process no. | Process size | Memory block |"
         << endl;
    cout << "+-------------+--------------+--------------+"
         << endl;
  
    // Traverse memory blocks size
    for (i = 0; i < memory_blocks.size(); i++) {
  
        // While memory block size is not empty
        while (!memory_blocks.at(i).empty()) {
            p = memory_blocks.at(i).pop();
            temp = to_string(p.no).length();
            cout << "|" << string(7 - temp / 2 - temp % 2, ' ')
                 << p.no << string(6 - temp / 2, ' ')
                 << "|";
  
            temp = to_string(p.size).length();
            cout << string(7 - temp / 2 - temp % 2, ' ')
                 << p.size
                 << string(7 - temp / 2, ' ') << "|";
  
            temp = to_string(memory_blocks.at(i).no).length();
            cout << string(7 - temp / 2 - temp % 2, ' ');
  
            // If memory blocks is assigned
            if (memory_blocks.at(i).no != -10) {
                cout << memory_blocks.at(i).no;
            }
  
            // Else memory blocks is assigned
            else {
                cout << "N/A";
            }
            cout << string(7 - temp / 2, ' ')
                 << "|" << endl;
        }
    }
    cout << "+-------------+--------------+--------------+"
         << endl;
}
  
// Driver Code
int main()
{
    // Declare memory blocks
  
    vector memory_blocks(5);
  
    // Declare worst fit blocks
    vector worst_fit_blocks;
  
    // Declare queue of all processess
    queue processess;
    process temp;
  
    // Set sample data
    memory_blocks[0].no = 1;
    memory_blocks[0].size = 400;
  
    memory_blocks[1].no = 2;
    memory_blocks[1].size = 500;
  
    memory_blocks[2].no = 3;
    memory_blocks[2].size = 300;
  
    memory_blocks[3].no = 4;
    memory_blocks[3].size = 200;
  
    memory_blocks[4].no = 5;
    memory_blocks[4].size = 100;
  
    temp.no = 1;
    temp.size = 88;
  
    // Push the process
    processess.push(temp);
    temp.no = 2;
    temp.size = 192;
  
    // Push the process
    processess.push(temp);
    temp.no = 3;
    temp.size = 277;
  
    // Push the process
    processess.push(temp);
    temp.no = 4;
    temp.size = 365;
  
    // Push the process
    processess.push(temp);
    temp.no = 5;
    temp.size = 489;
  
    // Push the process
    processess.push(temp);
  
    // Get the data
    worst_fit_blocks = worst_fit(memory_blocks,
                                 processess);
  
    // Display the data
    display(worst_fit_blocks);
    memory_blocks.clear();
    memory_blocks.shrink_to_fit();
    worst_fit_blocks.clear();
    worst_fit_blocks.shrink_to_fit();
    return 0;
}
输出:
+-------------+--------------+--------------+
| Process no. | Process size | Memory block |
+-------------+--------------+--------------+
|      3      |     277      |      1       |
|      1      |      88      |      2       |
|      2      |     192      |      2       |
|      4      |     365      |     N/A      |
|      5      |     489      |     N/A      |
+-------------+--------------+--------------+

4.最合适

此方法按大小从小到大的顺序排列忙/闲列表。在这种方法中,操作系统首先根据给定作业的大小搜索整个内存,然后将其分配给内存中最适合的空闲分区,从而使其能够有效地使用内存。这里的工作按从最小到最大的顺序排列。

以下是最佳拟合算法的实现:

// C++ program for the implementation
// of the Best Fit algorithm
#include 
#include 
#include 
using namespace std;
  
// Process Class
class process {
public:
    // Size & number of process
    size_t size;
    pid_t no;
};
  
// Memory Class
class memory {
public:
    size_t size;
  
    // Number of memory & queue of space
    // occupied by process
    pid_t no;
    queue space_occupied;
  
    // Function to push process in a block
    void push(const process p)
    {
        if (p.size <= size) {
            space_occupied.push(p);
            size -= p.size;
        }
    }
  
    // Function to pop and return the
    // process from the block
    process pop()
    {
        process p;
  
        // If space occupied is empty
        if (!space_occupied.empty()) {
            p = space_occupied.front();
            space_occupied.pop();
            size += p.size;
            return p;
        }
    }
  
    // Function to check if block is
    // completely empty
    bool empty()
    {
        return space_occupied.empty();
    }
};
  
// Function to get data of processess
// allocated using Best Fit
vector best_fit(vector memory_blocks,
                        queue processess)
{
    int i = 0, min, index = 0;
    memory na;
    na.no = -10;
  
    // Loop till processe is not empty
    while (!processess.empty()) {
        min = 0;
  
        // Traverse the memory_blocks
        for (i = 0; i < memory_blocks.size(); i++) {
            if (memory_blocks.at(i).size >= processess.front().size && (min == 0 || memory_blocks.at(i).size < min)) {
                min = memory_blocks.at(i).size;
                index = i;
            }
        }
  
        if (min != 0) {
            memory_blocks.at(index).push(processess.front());
        }
        else {
            na.size += processess.front().size;
            na.push(processess.front());
        }
  
        // Pop the processe
        processess.pop();
    }
  
    // If space is no occupied then push
    // the current memory na
    if (!na.space_occupied.empty()) {
        memory_blocks.push_back(na);
    }
  
    // Return the memory_blocks
    return memory_blocks;
}
  
// Function to display the allocation
// of all processess
void display(vector memory_blocks)
{
    int i = 0, temp = 0;
    process p;
    cout << "+-------------+--------------+--------------+"
         << endl;
    cout << "| Process no. | Process size | Memory block |"
         << endl;
    cout << "+-------------+--------------+--------------+"
         << endl;
  
    // Traverse memory blocks size
    for (i = 0; i < memory_blocks.size(); i++) {
  
        // While memory block size is not empty
        while (!memory_blocks.at(i).empty()) {
            p = memory_blocks.at(i).pop();
            temp = to_string(p.no).length();
            cout << "|" << string(7 - temp / 2 - temp % 2, ' ')
                 << p.no << string(6 - temp / 2, ' ')
                 << "|";
  
            temp = to_string(p.size).length();
            cout << string(7 - temp / 2 - temp % 2, ' ')
                 << p.size
                 << string(7 - temp / 2, ' ') << "|";
  
            temp = to_string(memory_blocks.at(i).no).length();
            cout << string(7 - temp / 2 - temp % 2, ' ');
  
            // If memory blocks is assigned
            if (memory_blocks.at(i).no != -10) {
                cout << memory_blocks.at(i).no;
            }
  
            // Else memory blocks is assigned
            else {
                cout << "N/A";
            }
            cout << string(7 - temp / 2, ' ')
                 << "|" << endl;
        }
    }
    cout << "+-------------+--------------+--------------+"
         << endl;
}
  
// Driver Code
int main()
{
    // Declare memory blocks
    vector memory_blocks(5);
  
    // Declare best fit blocks
    vector best_fit_blocks;
  
    // Declare queue of all processess
    queue processess;
    process temp;
  
    // Set sample data
    memory_blocks[0].no = 1;
    memory_blocks[0].size = 400;
  
    memory_blocks[1].no = 2;
    memory_blocks[1].size = 500;
  
    memory_blocks[2].no = 3;
    memory_blocks[2].size = 300;
  
    memory_blocks[3].no = 4;
    memory_blocks[3].size = 200;
  
    memory_blocks[4].no = 5;
    memory_blocks[4].size = 100;
  
    temp.no = 1;
    temp.size = 88;
  
    // Push the processe to queue
    processess.push(temp);
    temp.no = 2;
    temp.size = 192;
  
    // Push the processe to queue
    processess.push(temp);
    temp.no = 3;
    temp.size = 277;
  
    // Push the processe to queue
    processess.push(temp);
    temp.no = 4;
    temp.size = 365;
  
    // Push the processe to queue
    processess.push(temp);
    temp.no = 5;
    temp.size = 489;
  
    // Push the processe to queue
    processess.push(temp);
  
    // Get the data
    best_fit_blocks = best_fit(memory_blocks,
                               processess);
  
    // Display the data
    display(best_fit_blocks);
    memory_blocks.clear();
    memory_blocks.shrink_to_fit();
    best_fit_blocks.clear();
    best_fit_blocks.shrink_to_fit();
    return 0;
}
输出:
+-------------+--------------+--------------+
| Process no. | Process size | Memory block |
+-------------+--------------+--------------+
|      4      |     365      |      1       |
|      5      |     489      |      2       |
|      3      |     277      |      3       |
|      2      |     192      |      4       |
|      1      |      88      |      5       |
+-------------+--------------+--------------+
想要从精选的最佳视频中学习并解决问题,请查看有关从基础到高级C++的C++基础课程以及有关语言和STL的C++ STL课程。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”