1000.5.CS.OS.1.3-基础-内存管理-堆管理算法-Created: 2024-06-09.Sunday10:41
文章目录
- 1 内存分配算法概述
- 1.1 首次适应(First-Fit)
- 1.2 最佳适应(Best-Fit)
- 2 伙伴系统(Buddy System)
- 3 总结
- References
在操作系统和程序设计中,内存管理是一个至关重要的环节。不同的堆分配和管理算法,如首次适应(first-fit)、最佳适应(best-fit)和伙伴系统(buddy system),在内存分配和管理中发挥着重要作用。这篇文章将深入探讨这些算法,并通过示例代码展示其实现。
1 内存分配算法概述
内存分配算法用于动态地分配和释放内存,以便程序能够高效地使用系统资源。以下是一些常见的堆分配和管理算法:
1.1 首次适应(First-Fit)
首次适应算法是一种简单且快速的内存分配算法。它从头开始扫描内存分区表,找到第一个足够大的空闲块,并分配给请求的进程。
优点:
- 快速:由于从头开始扫描,通常能迅速找到合适的空闲块。
- 简单:实现和理解都较为简单。
缺点:
- 内存碎片:容易产生外部碎片,导致内存利用率下降。
示例代码:
#include <iostream>
#include <vector>struct Block {int size;bool free;Block(int s) : size(s), free(true) {}
};class FirstFitAllocator {
public:FirstFitAllocator(std::vector<int> blockSizes) {for (int size : blockSizes) {blocks.push_back(Block(size));}}void* allocate(int requestSize) {for (Block& block : blocks) {if (block.free && block.size >= requestSize) {block.free = false;return █}}return nullptr; // Allocation failed}void deallocate(void* ptr) {Block* block = static_cast<Block*>(ptr);block->free = true;}private:std::vector<Block> blocks;
};int main() {FirstFitAllocator allocator({100, 500, 200, 300, 600});void* ptr1 = allocator.allocate(150);void* ptr2 = allocator.allocate(100);allocator.deallocate(ptr1);void* ptr3 = allocator.allocate(50);return 0;
}
1.2 最佳适应(Best-Fit)
最佳适应算法通过扫描整个内存分区表,找到最接近请求大小的空闲块进行分配。这种方法尽量减少剩余的空闲块,降低外部碎片的产生。
优点:
- 内存利用率高:通过分配最接近大小的空闲块,减少了外部碎片。
- 有效:在内存资源紧张的情况下表现较好。
缺点:
- 扫描时间长:需要扫描整个内存分区表,可能导致分配时间较长。
示例代码:
#include <iostream>
#include <vector>
#include <limits>struct Block {int size;bool free;Block(int s) : size(s), free(true) {}
};class BestFitAllocator {
public:BestFitAllocator(std::vector<int> blockSizes) {for (int size : blockSizes) {blocks.push_back(Block(size));}}void* allocate(int requestSize) {int bestFitIndex = -1;int minDiff = std::numeric_limits<int>::max();for (int i = 0; i < blocks.size(); ++i) {if (blocks[i].free && blocks[i].size >= requestSize) {int diff = blocks[i].size - requestSize;if (diff < minDiff) {minDiff = diff;bestFitIndex = i;}}}if (bestFitIndex != -1) {blocks[bestFitIndex].free = false;return &blocks[bestFitIndex];}return nullptr; // Allocation failed}void deallocate(void* ptr) {Block* block = static_cast<Block*>(ptr);block->free = true;}private:std::vector<Block> blocks;
};int main() {BestFitAllocator allocator({100, 500, 200, 300, 600});void* ptr1 = allocator.allocate(150);void* ptr2 = allocator.allocate(100);allocator.deallocate(ptr1);void* ptr3 = allocator.allocate(50);return 0;
}
2 伙伴系统(Buddy System)
伙伴系统是一种平衡了首次适应和最佳适应优点的内存分配算法。它将内存分割成大小为2的幂次方的块,当需要分配内存时,会找到最小的满足请求的块。如果块大小过大,会将其分割成两个“伙伴”块,并继续分配。
优点:
- 内存碎片少:由于采用幂次方块,容易合并相邻空闲块,减少碎片。
- 分配和释放效率高:通过伙伴系统,分配和释放操作较为高效。
缺点:
- 内存浪费:有时会由于块大小限制,导致内存浪费。
示例代码:
#include <iostream>
#include <vector>
#include <cmath>class BuddyAllocator {
public:BuddyAllocator(int size) {int n = std::ceil(std::log2(size));maxSize = 1 << n;freeBlocks.resize(n + 1);freeBlocks[n].push_back(0);}void* allocate(int size) {int n = std::ceil(std::log2(size));for (int i = n; i < freeBlocks.size(); ++i) {if (!freeBlocks[i].empty()) {int block = freeBlocks[i].back();freeBlocks[i].pop_back();while (i > n) {--i;int buddy = block ^ (1 << i);freeBlocks[i].push_back(buddy);}return reinterpret_cast<void*>(block * minBlockSize);}}return nullptr; // Allocation failed}void deallocate(void* ptr) {int block = reinterpret_cast<int>(ptr) / minBlockSize;int size = 1;while (true) {int buddy = block ^ size;auto it = std::find(freeBlocks[std::log2(size)].begin(), freeBlocks[std::log2(size)].end(), buddy);if (it == freeBlocks[std::log2(size)].end()) {freeBlocks[std::log2(size)].push_back(block);break;}freeBlocks[std::log2(size)].erase(it);block &= ~size;size <<= 1;}}private:int maxSize;int minBlockSize = 1;std::vector<std::vector<int>> freeBlocks;
};int main() {BuddyAllocator allocator(1024);void* ptr1 = allocator.allocate(100);void* ptr2 = allocator.allocate(200);allocator.deallocate(ptr1);void* ptr3 = allocator.allocate(50);return 0;
}
3 总结
通过了解不同的内存分配算法,我们可以更好地优化程序的内存使用,提高系统的性能和稳定性。希望这篇文章不仅能为你带来技术上的提升,还能激发你对内存管理的兴趣和热情。
在实际项目中,你使用过哪些内存分配算法?它们在你的项目中表现如何?欢迎在评论区分享你的经验和见解,与其他读者互动,共同探讨内存管理的最佳实践。