#pragma once #include #include #include #include #include #include #include #include #include #include #include #include namespace extra2d { // ============================================================================ // 对象池 - 自动管理的高性能内存池 // 特性: // - 自动内存对齐 // - 侵入式空闲链表(零额外内存开销) // - 线程本地缓存(减少锁竞争) // - 自动容量管理(自动扩展/收缩) // - 自动预热 // - 异常安全 // ============================================================================ // 线程本地缓存配置 struct PoolConfig { static constexpr size_t DEFAULT_BLOCK_SIZE = 64; static constexpr size_t THREAD_CACHE_SIZE = 16; static constexpr size_t SHRINK_THRESHOLD_MS = 30000; static constexpr double SHRINK_RATIO = 0.5; }; template class ObjectPool { public: static_assert(std::is_default_constructible_v, "T must be default constructible"); static_assert(std::is_destructible_v, "T must be destructible"); static_assert(BlockSize > 0, "BlockSize must be greater than 0"); static_assert(alignof(T) <= alignof(std::max_align_t), "Alignment requirement too high"); ObjectPool() : freeListHead_(nullptr) , blocks_() , allocatedCount_(0) , totalCapacity_(0) , isDestroyed_(false) , lastShrinkCheck_(0) , prewarmed_(false) { } ~ObjectPool() { clear(); } ObjectPool(const ObjectPool&) = delete; ObjectPool& operator=(const ObjectPool&) = delete; ObjectPool(ObjectPool&&) noexcept = delete; ObjectPool& operator=(ObjectPool&&) noexcept = delete; /** * @brief 分配一个对象(自动预热、自动扩展) * @return 指向分配的对象的指针,失败返回 nullptr */ T* allocate() { auto& cache = getThreadCache(); if (T* obj = cache.pop()) { new (obj) T(); allocatedCount_.fetch_add(1, std::memory_order_relaxed); return obj; } std::lock_guard lock(mutex_); if (isDestroyed_) { return nullptr; } if (!prewarmed_) { prewarmInternal(); } if (!freeListHead_) { growInternal(); } T* obj = popFreeList(); if (obj) { new (obj) T(); allocatedCount_.fetch_add(1, std::memory_order_relaxed); } return obj; } /** * @brief 分配并构造一个对象(带参数) */ template T* allocate(Args&&... args) { auto& cache = getThreadCache(); if (T* obj = cache.pop()) { new (obj) T(std::forward(args)...); allocatedCount_.fetch_add(1, std::memory_order_relaxed); return obj; } std::lock_guard lock(mutex_); if (isDestroyed_) { return nullptr; } if (!prewarmed_) { prewarmInternal(); } if (!freeListHead_) { growInternal(); } T* obj = popFreeList(); if (obj) { new (obj) T(std::forward(args)...); allocatedCount_.fetch_add(1, std::memory_order_relaxed); } return obj; } /** * @brief 回收一个对象(自动异常处理) * @param obj 要回收的对象指针 * @return true 如果对象成功回收 */ bool deallocate(T* obj) { if (!obj) { return false; } try { obj->~T(); } catch (const std::exception& e) { Logger::log(LogLevel::Error, "ObjectPool: Exception in destructor: {}", e.what()); } catch (...) { Logger::log(LogLevel::Error, "ObjectPool: Unknown exception in destructor"); } auto& cache = getThreadCache(); if (cache.push(obj)) { allocatedCount_.fetch_sub(1, std::memory_order_relaxed); return true; } std::lock_guard lock(mutex_); if (!isDestroyed_) { pushFreeList(obj); allocatedCount_.fetch_sub(1, std::memory_order_relaxed); tryAutoShrink(); return true; } return false; } /** * @brief 获取当前已分配的对象数量 */ size_t allocatedCount() const { return allocatedCount_.load(std::memory_order_relaxed); } /** * @brief 获取池中总的对象容量 */ size_t capacity() const { return totalCapacity_.load(std::memory_order_relaxed); } /** * @brief 获取内存使用量(字节) */ size_t memoryUsage() const { std::lock_guard lock(mutex_); return blocks_.size() * BlockSize * sizeof(T); } /** * @brief 清空所有内存块 */ void clear() { std::lock_guard lock(mutex_); isDestroyed_ = true; for (auto& block : blocks_) { alignedFree(block); } blocks_.clear(); freeListHead_ = nullptr; totalCapacity_.store(0, std::memory_order_relaxed); allocatedCount_.store(0, std::memory_order_relaxed); } private: struct FreeNode { FreeNode* next; }; struct ThreadCache { T* objects[PoolConfig::THREAD_CACHE_SIZE]; size_t count = 0; T* pop() { if (count > 0) { return objects[--count]; } return nullptr; } bool push(T* obj) { if (count < PoolConfig::THREAD_CACHE_SIZE) { objects[count++] = obj; return true; } return false; } void clear() { count = 0; } }; static ThreadCache& getThreadCache() { thread_local ThreadCache cache; return cache; } static constexpr size_t Alignment = alignof(T); static constexpr size_t AlignedSize = ((sizeof(T) + Alignment - 1) / Alignment) * Alignment; static void* alignedAlloc(size_t size) { #ifdef _WIN32 return _aligned_malloc(size, Alignment); #else return std::aligned_alloc(Alignment, size); #endif } static void alignedFree(void* ptr) { #ifdef _WIN32 _aligned_free(ptr); #else std::free(ptr); #endif } void prewarmInternal() { if (!freeListHead_) { growInternal(); } prewarmed_ = true; } void growInternal() { size_t blockSize = AlignedSize > sizeof(FreeNode) ? AlignedSize : sizeof(FreeNode); size_t totalSize = blockSize * BlockSize; void* block = alignedAlloc(totalSize); if (!block) { Logger::log(LogLevel::Error, "ObjectPool: Failed to allocate memory block"); return; } blocks_.push_back(block); totalCapacity_.fetch_add(BlockSize, std::memory_order_relaxed); char* ptr = static_cast(block); for (size_t i = 0; i < BlockSize; ++i) { pushFreeList(reinterpret_cast(ptr + i * blockSize)); } } void pushFreeList(T* obj) { FreeNode* node = reinterpret_cast(obj); node->next = freeListHead_; freeListHead_ = node; } T* popFreeList() { if (!freeListHead_) { return nullptr; } FreeNode* node = freeListHead_; freeListHead_ = freeListHead_->next; return reinterpret_cast(node); } void tryAutoShrink() { auto now = std::chrono::steady_clock::now(); auto elapsed = std::chrono::duration_cast( now.time_since_epoch()).count(); if (elapsed - lastShrinkCheck_ < PoolConfig::SHRINK_THRESHOLD_MS) { return; } lastShrinkCheck_ = elapsed; size_t allocated = allocatedCount_.load(std::memory_order_relaxed); size_t capacity = totalCapacity_.load(std::memory_order_relaxed); if (capacity > BlockSize && static_cast(allocated) / capacity < PoolConfig::SHRINK_RATIO) { shrinkInternal(); } } void shrinkInternal() { size_t toFree = 0; size_t freeCount = 0; FreeNode* node = freeListHead_; while (node) { ++freeCount; node = node->next; } if (freeCount < BlockSize) { return; } size_t blocksToKeep = blocks_.size(); if (allocatedCount_.load(std::memory_order_relaxed) > 0) { blocksToKeep = (allocatedCount_.load() + BlockSize - 1) / BlockSize; blocksToKeep = std::max(blocksToKeep, size_t(1)); } if (blocksToKeep >= blocks_.size()) { return; } size_t blocksToRemove = blocks_.size() - blocksToKeep; for (size_t i = 0; i < blocksToRemove; ++i) { if (blocks_.empty()) break; void* block = blocks_.back(); blocks_.pop_back(); alignedFree(block); totalCapacity_.fetch_sub(BlockSize, std::memory_order_relaxed); } rebuildFreeList(); } void rebuildFreeList() { freeListHead_ = nullptr; size_t blockSize = AlignedSize > sizeof(FreeNode) ? AlignedSize : sizeof(FreeNode); for (void* block : blocks_) { char* ptr = static_cast(block); for (size_t i = 0; i < BlockSize; ++i) { pushFreeList(reinterpret_cast(ptr + i * blockSize)); } } } mutable std::mutex mutex_; FreeNode* freeListHead_; std::vector blocks_; std::atomic allocatedCount_; std::atomic totalCapacity_; bool isDestroyed_; uint64_t lastShrinkCheck_; bool prewarmed_; }; // ============================================================================ // 智能指针支持的内存池分配器 // ============================================================================ template class PooledAllocator { public: using PoolType = ObjectPool; PooledAllocator() : pool_(std::make_shared()) {} explicit PooledAllocator(std::shared_ptr pool) : pool_(pool) {} /** * @brief 创建一个使用内存池的对象(自动管理) */ template Ptr makeShared(Args&&... args) { std::weak_ptr weakPool = pool_; T* obj = pool_->allocate(std::forward(args)...); if (!obj) { return nullptr; } return Ptr(obj, Deleter{weakPool}); } /** * @brief 获取底层内存池 */ std::shared_ptr getPool() const { return pool_; } private: struct Deleter { std::weak_ptr pool; void operator()(T* obj) const { if (auto sharedPool = pool.lock()) { if (!sharedPool->deallocate(obj)) { Logger::log(LogLevel::Warn, "PooledAllocator: Pool destroyed, memory leaked"); } } else { Logger::log(LogLevel::Warn, "PooledAllocator: Pool expired during deallocation"); } } }; std::shared_ptr pool_; }; // ============================================================================ // 全局内存池管理器 - 自动管理所有池的生命周期 // ============================================================================ class ObjectPoolManager { public: static ObjectPoolManager& getInstance() { static ObjectPoolManager instance; return instance; } /** * @brief 获取指定类型的内存池(自动管理) */ template std::shared_ptr> getPool() { static auto pool = std::make_shared>(); return pool; } /** * @brief 创建使用内存池的对象(自动管理) */ template Ptr makePooled(Args&&... args) { auto pool = getPool(); std::weak_ptr> weakPool = pool; T* obj = pool->allocate(std::forward(args)...); if (!obj) { return nullptr; } return Ptr(obj, [weakPool](T* p) { if (auto sharedPool = weakPool.lock()) { if (!sharedPool->deallocate(p)) { Logger::log(LogLevel::Warn, "ObjectPoolManager: Pool destroyed during deallocation"); } } else { Logger::log(LogLevel::Warn, "ObjectPoolManager: Pool expired"); } }); } private: ObjectPoolManager() = default; ~ObjectPoolManager() = default; ObjectPoolManager(const ObjectPoolManager&) = delete; ObjectPoolManager& operator=(const ObjectPoolManager&) = delete; }; // ============================================================================ // 内存池宏定义(便于使用) // ============================================================================ #define E2D_DECLARE_POOL(T, BlockSize) \ static extra2d::ObjectPool& getPool() { \ static extra2d::ObjectPool pool; \ return pool; \ } #define E2D_MAKE_POOLED(T, ...) \ extra2d::ObjectPoolManager::getInstance().makePooled(__VA_ARGS__) } // namespace extra2d