MST
星途 面试题库

面试题:C++内存池实现及优化

请设计并实现一个简单的C++内存池,用于高效管理小块内存的分配和释放。要求考虑内存碎片问题、线程安全问题,并阐述在不同应用场景下如何对该内存池进行优化。
27.6万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

1. 设计思路

  1. 内存块划分:将大块内存划分成固定大小的小块,以减少内存碎片。
  2. 空闲链表:使用链表来管理空闲的内存块,方便快速分配和回收。
  3. 线程安全:使用互斥锁(std::mutex)来保证多线程环境下内存池操作的线程安全。

2. 代码实现

#include <iostream>
#include <vector>
#include <mutex>

class MemoryPool {
private:
    const size_t blockSize;
    const size_t poolSize;
    std::vector<char*> blocks;
    char* pool;
    std::mutex mtx;
    struct FreeListNode {
        FreeListNode* next;
    };
    FreeListNode* freeList;

public:
    MemoryPool(size_t blockSize, size_t numBlocks)
        : blockSize(blockSize), poolSize(numBlocks * blockSize), freeList(nullptr) {
        pool = new char[poolSize];
        for (size_t i = 0; i < numBlocks; ++i) {
            char* block = pool + i * blockSize;
            blocks.push_back(block);
            FreeListNode* node = reinterpret_cast<FreeListNode*>(block);
            node->next = freeList;
            freeList = node;
        }
    }

    ~MemoryPool() {
        delete[] pool;
    }

    void* allocate() {
        std::lock_guard<std::mutex> lock(mtx);
        if (freeList == nullptr) {
            return nullptr;
        }
        FreeListNode* node = freeList;
        freeList = freeList->next;
        return node;
    }

    void deallocate(void* ptr) {
        std::lock_guard<std::mutex> lock(mtx);
        FreeListNode* node = reinterpret_cast<FreeListNode*>(ptr);
        node->next = freeList;
        freeList = node;
    }
};

3. 内存碎片问题处理

  • 固定大小块:通过分配固定大小的内存块,减少因不同大小内存请求导致的外部碎片。
  • 合并空闲块:对于相邻的空闲块,可以在释放时进行合并,减少内部碎片。

4. 线程安全问题处理

  • 互斥锁:使用std::mutex来保护对空闲链表的操作,确保在多线程环境下内存池操作的原子性。

5. 不同应用场景下的优化

  • 高并发读场景:可以考虑使用读写锁(std::shared_mutex),允许多个线程同时进行读操作,提高并发性能。
  • 不同大小内存请求:可以设计多个不同大小块的内存池,根据请求大小选择合适的内存池进行分配。
  • 长时间运行应用:定期进行内存碎片整理,例如在空闲时段合并空闲块,以维持高效的内存分配。