内存碎片是指由于频繁的内存分配和释放,导致内存中出现大量的碎片空间,无法被有效利用。特别是在长期运行的程序中,内存碎片会导致内存使用效率下降,甚至可能导致分配失败。
1、使用内存池(Memory Pool):
内存池预先分配一大块内存,并根据需要从中分配小块内存。这样可以减少频繁的 new 和 delete 操作,降低内存碎片的风险。
class MemoryPool {
private:
std::vector<void*> pool;
size_t blockSize;
size_t poolSize;
public:
MemoryPool(size_t blockSize, size_t poolSize) : blockSize(blockSize), poolSize(poolSize) {
for (size_t i = 0; i < poolSize; ++i) {
pool.push_back(std::malloc(blockSize));
}
}
~MemoryPool() {
for (auto block : pool) {
std::free(block);
}
}
void* allocate() {
if (pool.empty()) {
return std::malloc(blockSize);
} else {
void* block = pool.back();
pool.pop_back();
return block;
}
}
void deallocate(void* block) {
pool.push_back(block);
}
};
MemoryPool pool(sizeof(MyClass), 100);
void* operator new(size_t size) {
return pool.allocate();
}
void operator delete(void* pointer) {
pool.deallocate(pointer);
}
2、使用智能指针(Smart Pointers)
智能指针如 std::shared_ptr 和 std::unique_ptr 自动管理内存生命周期,减少内存泄漏的可能性,间接降低内存碎片。
#include <memory>
void example() {
std::unique_ptr<int> ptr1 = std::make_unique<int>(5);
std::shared_ptr<int> ptr2 = std::make_shared<int>(10);
}
3、自定义分配器(Custom Allocator):
自定义分配器可以更细粒度地控制内存分配策略,减少碎片。
template <typename T>
class CustomAllocator {
public:
using value_type = T;
CustomAllocator() = default;
template <typename U>
constexpr CustomAllocator(const CustomAllocator<U>&) noexcept {}
T* allocate(std::size_t n) {
if (n > std::size_t(-1) / sizeof(T))
throw std::bad_alloc();
if (auto p = static_cast<T*>(std::malloc(n * sizeof(T)))) {
return p;
}
throw std::bad_alloc();
}
void deallocate(T* p, std::size_t) noexcept {
std::free(p);
}
};
实例
#include <iostream>
#include <vector>
class MemoryPool {
private:
std::vector<void*> pool; // 存储可用内存块的容器
size_t blockSize; // 每个内存块的大小
size_t poolSize; // 内存池的大小(即预分配的内存块数)
public:
//构造函数接受每个内存块的大小 (blockSize) 和池的大小 (poolSize)。通过 std::malloc 分配指定大小的内存块,并将这些块添加到 pool 中。
MemoryPool(size_t blockSize, size_t poolSize) : blockSize(blockSize), poolSize(poolSize) {
for (size_t i = 0; i < poolSize; ++i) {
pool.push_back(std::malloc(blockSize)); // 分配内存块并存储到池中
}
}
~MemoryPool() {
for (auto block : pool) {
std::free(block); // 析构函数遍历 pool 中的所有内存块,并调用 std::free 释放它们。
}
}
void* allocate() {
if (pool.empty()) {
return std::malloc(blockSize); // 如果池为空,分配新的内存块
} else {
void* block = pool.back();// 从池中取出一个内存块
pool.pop_back();
return block;
}
}
//deallocate 方法将内存块添加回 pool,以便后续可以重用。
void deallocate(void* block) {
pool.push_back(block);
}
};
MemoryPool pool(sizeof(int), 100);
//重载的 new 操作符调用 pool.allocate(),从内存池中分配内存。
void* operator new(size_t size) {
return pool.allocate();
}
//重载的 delete 操作符调用 pool.deallocate(),将内存块放回内存池中。
void operator delete(void* pointer) {
pool.deallocate(pointer);
}
int main() {
//new int(5) 和 new int(10) 使用重载的 new 操作符,实际会通过 MemoryPool 分配内存。delete p1 和 delete p2 使用重载的 delete 操作符,实际会通过 MemoryPool 释放内存。
int* p1 = new int(5);
int* p2 = new int(10);
delete p1;
delete p2;
return 0;
}