C++ 手写一个内存池

发布于:2025-05-09 ⋅ 阅读:(18) ⋅ 点赞:(0)

内存池是一种内存管理技术,它预先分配一大块内存,之后将其按需分割成多个小块供程序使用。下面将详细阐述它的好处以及适用场景。

内存池的好处

  1. 减少内存碎片:在动态内存分配时,频繁地分配和释放不同大小的内存块,会使得内存空间出现许多小块的、不连续的空闲内存,也就是内存碎片。这可能导致后续即使有足够的总空闲内存,也无法分配出大块连续内存。内存池预先分配连续的大块内存,然后按需分配小块,能够有效减少内存碎片的产生。
  2. 提升性能:每次使用系统调用(如 mallocfree)进行内存分配和释放时,会涉及到内核态和用户态的切换,开销较大。内存池通过预先分配内存,在需要时直接从池中获取,避免了频繁的系统调用,从而显著提高了内存分配和释放的速度。
  3. 可预测性:使用内存池可以更好地控制内存的使用,程序能够预先知道可用内存的大小和分配情况,有助于进行内存管理和优化,避免因内存耗尽导致的程序崩溃。

适用场景

  1. 频繁进行内存分配和释放的场景:在一些需要频繁创建和销毁对象的应用程序中,例如游戏开发中频繁创建和销毁游戏角色、粒子效果等,使用内存池可以避免频繁的系统调用,提高程序的性能。
  2. 对内存碎片敏感的场景:某些实时系统或嵌入式系统,对内存的连续性要求较高。内存碎片可能导致无法分配大块连续内存,影响系统的正常运行。使用内存池可以有效减少内存碎片,保证系统的稳定性。
  3. 对性能要求较高的场景:在高并发的服务器程序中,如 Web 服务器、数据库服务器等,每秒可能会处理大量的请求,每个请求可能都需要分配和释放内存。使用内存池可以显著提高内存分配和释放的速度,从而提升服务器的整体性能。

 一:简单的内存池来管理固定数量的内存块

#include <iostream>
#include <vector>

// 内存池类
class MemoryPool {
private:
    // 块大小
    size_t blockSize;
    // 块数量
    size_t blockCount;
    // 空闲块列表
    std::vector<void*> freeList;

public:
    MemoryPool(size_t blockSize, size_t blockCount) : blockSize(blockSize), blockCount(blockCount) {
        for (size_t i = 0; i < blockCount; ++i) {
            void* block = ::operator new(blockSize);
            freeList.push_back(block);
        }
    }

    ~MemoryPool() {
        for (void* block : freeList) {
            ::operator delete(block);
        }
    }

    // 从内存池分配内存
    void* allocate() {
        if (freeList.empty()) {
            return nullptr;
        }
        void* block = freeList.back();
        freeList.pop_back();
        return block;
    }

    // 将内存释放回内存池
    void deallocate(void* block) {
        freeList.push_back(block);
    }
};

// 测试函数
void testMemoryPool() {
    MemoryPool pool(1024, 10);

    std::vector<void*> allocatedBlocks;

    // 分配内存
    for (size_t i = 0; i < 5; ++i) {
        void* block = pool.allocate();
        if (block) {
            allocatedBlocks.push_back(block);
            std::cout << "Allocated block at address: " << block << std::endl;
        } else {
            std::cout << "No available blocks in the pool." << std::endl;
        }
    }

    // 释放内存
    for (void* block : allocatedBlocks) {
        pool.deallocate(block);
        std::cout << "Deallocated block at address: " << block << std::endl;
    }
}

int main() {
    testMemoryPool();
    return 0;
}    

 

 


网站公告

今日签到

点亮在社区的每一天
去签到