如何避免内存碎片?

内存碎片是指由于频繁的内存分配和释放,导致内存中出现大量的碎片空间,无法被有效利用。特别是在长期运行的程序中,内存碎片会导致内存使用效率下降,甚至可能导致分配失败。
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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值